test_fails_asr_to_manual_and_ignores_other_conversation_snapshot (test_voice_messages.VisualVoiceTests.test_fails_asr_to_manual_and_ignores_other_conversation_snapshot) ... ok test_timeout_notifies_manual_instead_of_sending_guess (test_voice_messages.VisualVoiceTests.test_timeout_notifies_manual_instead_of_sending_guess) ... ok test_waits_without_manual_state_then_allows_transcribed_text (test_voice_messages.VisualVoiceTests.test_waits_without_manual_state_then_allows_transcribed_text) ... ok test_ambiguous_files_and_other_account_do_not_enqueue (test_voice_messages.VoiceDatabaseTests.test_ambiguous_files_and_other_account_do_not_enqueue) ... ok test_cache_collision_across_conversations_is_rejected (test_voice_messages.VoiceDatabaseTests.test_cache_collision_across_conversations_is_rejected) ... ok test_cache_update_on_same_message_becomes_visible_without_new_incoming (test_voice_messages.VoiceDatabaseTests.test_cache_update_on_same_message_becomes_visible_without_new_incoming) ... ok test_empty_asr_result_is_error_not_answer (test_voice_messages.VoiceDatabaseTests.test_empty_asr_result_is_error_not_answer) ... ok test_exact_current_account_path_enqueues_then_returns_transcript (test_voice_messages.VoiceDatabaseTests.test_exact_current_account_path_enqueues_then_returns_transcript) ... ok test_missing_table_and_empty_text_are_not_transcriptions (test_voice_messages.VoiceDatabaseTests.test_missing_table_and_empty_text_are_not_transcriptions) ... ok test_mixed_batch_waits_for_all_voices_and_rejects_foreign_binding (test_voice_messages.VoiceDatabaseTests.test_mixed_batch_waits_for_all_voices_and_rejects_foreign_binding) ... ok test_old_history_and_voice_before_human_reply_are_not_enqueued (test_voice_messages.VoiceDatabaseTests.test_old_history_and_voice_before_human_reply_are_not_enqueued) ... ok test_reads_server_id_cache_as_real_text_preserving_voice_type (test_voice_messages.VoiceDatabaseTests.test_reads_server_id_cache_as_real_text_preserving_voice_type) ... ok test_row_id_is_not_server_id_and_binary_payload_never_reaches_model (test_voice_messages.VoiceDatabaseTests.test_row_id_is_not_server_id_and_binary_payload_never_reaches_model) ... ok test_same_server_id_in_other_account_is_not_used (test_voice_messages.VoiceDatabaseTests.test_same_server_id_in_other_account_is_not_used) ... ok test_accounts_conversations_and_message_ids_do_not_share_results (test_voice_transcription.VoiceTranscriptionTests.test_accounts_conversations_and_message_ids_do_not_share_results) ... FAIL test_bad_header_is_not_sent_to_model (test_voice_transcription.VoiceTranscriptionTests.test_bad_header_is_not_sent_to_model) ... ok test_change_during_recognition_drops_old_result (test_voice_transcription.VoiceTranscriptionTests.test_change_during_recognition_drops_old_result) ... FAIL test_close_discards_text_and_stops_new_jobs (test_voice_transcription.VoiceTranscriptionTests.test_close_discards_text_and_stops_new_jobs) ... FAIL test_duration_limit_rejects_instead_of_truncating (test_voice_transcription.VoiceTranscriptionTests.test_duration_limit_rejects_instead_of_truncating) ... FAIL test_empty_recognition_never_becomes_ready (test_voice_transcription.VoiceTranscriptionTests.test_empty_recognition_never_becomes_ready) ... FAIL test_failures_back_off_and_do_not_leak_exception_details (test_voice_transcription.VoiceTranscriptionTests.test_failures_back_off_and_do_not_leak_exception_details) ... FAIL test_group_wrong_account_self_invalid_server_denied (test_voice_transcription.VoiceTranscriptionTests.test_group_wrong_account_self_invalid_server_denied) ... ok test_invalid_model_manifest_fails_without_network (test_voice_transcription.VoiceTranscriptionTests.test_invalid_model_manifest_fails_without_network) ... ok test_missing_allowed_root_rejected (test_voice_transcription.VoiceTranscriptionTests.test_missing_allowed_root_rejected) ... ok test_missing_file_has_readable_error_without_path (test_voice_transcription.VoiceTranscriptionTests.test_missing_file_has_readable_error_without_path) ... ok test_missing_model_fails_without_network (test_voice_transcription.VoiceTranscriptionTests.test_missing_model_fails_without_network) ... FAIL test_model_loading_is_forced_offline (test_voice_transcription.VoiceTranscriptionTests.test_model_loading_is_forced_offline) ... ok test_outside_root_rejected (test_voice_transcription.VoiceTranscriptionTests.test_outside_root_rejected) ... ok test_queue_is_bounded (test_voice_transcription.VoiceTranscriptionTests.test_queue_is_bounded) ... FAIL test_request_is_fast_while_worker_waits (test_voice_transcription.VoiceTranscriptionTests.test_request_is_fast_while_worker_waits) ... FAIL test_same_message_changed_audio_is_not_cached (test_voice_transcription.VoiceTranscriptionTests.test_same_message_changed_audio_is_not_cached) ... FAIL test_same_message_same_audio_is_recognized_once (test_voice_transcription.VoiceTranscriptionTests.test_same_message_same_audio_is_recognized_once) ... FAIL test_silence_is_not_sent_to_model (test_voice_transcription.VoiceTranscriptionTests.test_silence_is_not_sent_to_model) ... FAIL test_silk_real_decode_of_synthetic_pcm (test_voice_transcription.VoiceTranscriptionTests.test_silk_real_decode_of_synthetic_pcm) ... ERROR test_size_limit_prevents_worker (test_voice_transcription.VoiceTranscriptionTests.test_size_limit_prevents_worker) ... ok test_wav_transcribes_and_preserves_digest (test_voice_transcription.VoiceTranscriptionTests.test_wav_transcribes_and_preserves_digest) ... ERROR test_failed_transcription_enters_manual_and_never_calls_model (test_protocol_voice.ProtocolVoiceTests.test_failed_transcription_enters_manual_and_never_calls_model) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 当前消息需要人工处理;语音自动转文字失败(empty_audio),请人工核对 ok test_human_reply_while_voice_pending_discards_old_question (test_protocol_voice.ProtocolVoiceTests.test_human_reply_while_voice_pending_discards_old_question) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 语音正在本机转文字 ok test_missing_voice_times_out_without_global_stop_or_guess (test_protocol_voice.ProtocolVoiceTests.test_missing_voice_times_out_without_global_stop_or_guess) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 等待企业微信语音文件或转写缓存 [协议处理] 同名客户 · 当前消息需要人工处理;语音转文字等待超时,尚未取得可核验文字,请人工处理 ok test_mixed_voice_and_text_waits_and_preserves_both (test_protocol_voice.ProtocolVoiceTests.test_mixed_voice_and_text_waits_and_preserves_both) ... [协议收信] 同名客户 · 已加入回复队列 [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 语音正在本机转文字 [协议处理] 同名客户 · 根据当前会话生成回复 [协议处理] 同名客户 · 原账号单聊发送 [协议发送成功] 同名客户 · 服务器消息 999 ok test_new_media_after_voice_still_needs_manual (test_protocol_voice.ProtocolVoiceTests.test_new_media_after_voice_still_needs_manual) ... [协议收信] 同名客户 · 已加入回复队列 [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 当前消息需要人工处理;当前未回复消息包含图片、语音或其他非文本内容,协议版需人工处理 ok test_pending_voice_delays_only_its_conversation_then_resumes_on_cache_update (test_protocol_voice.ProtocolVoiceTests.test_pending_voice_delays_only_its_conversation_then_resumes_on_cache_update) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 语音正在本机转文字 [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 根据当前会话生成回复 [协议处理] 同名客户 · 原账号单聊发送 [协议发送成功] 同名客户 · 服务器消息 999 [协议处理] 同名客户 · 根据当前会话生成回复 [协议处理] 同名客户 · 原账号单聊发送 [协议发送成功] 同名客户 · 服务器消息 999 ok test_spoofed_or_cross_conversation_transcription_does_not_reach_model (test_protocol_voice.ProtocolVoiceTests.test_spoofed_or_cross_conversation_transcription_does_not_reach_model) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 等待企业微信语音文件或转写缓存 ok test_transcribed_voice_reaches_model_and_selective_review_as_text (test_protocol_voice.ProtocolVoiceTests.test_transcribed_voice_reaches_model_and_selective_review_as_text) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 根据当前会话生成回复 [协议处理] 同名客户 · 合成审核规则 ok test_active_send_and_unresolved_receipt_phase_never_complete (test_protocol_manual_assistant.ProtocolManualAssistantTests.test_active_send_and_unresolved_receipt_phase_never_complete) ... ok test_cancelled_manual_task_does_not_restore_global_auto_mode (test_protocol_manual_assistant.ProtocolManualAssistantTests.test_cancelled_manual_task_does_not_restore_global_auto_mode) ... ok test_explicit_disabled_or_cancel_requested_tasks_are_not_resumed (test_protocol_manual_assistant.ProtocolManualAssistantTests.test_explicit_disabled_or_cancel_requested_tasks_are_not_resumed) ... ok test_failed_send_can_finish_only_on_later_human_evidence (test_protocol_manual_assistant.ProtocolManualAssistantTests.test_failed_send_can_finish_only_on_later_human_evidence) ... ok test_further_incoming_text_preserves_manual_episode_until_human_reply (test_protocol_manual_assistant.ProtocolManualAssistantTests.test_further_incoming_text_preserves_manual_episode_until_human_reply) ... ok test_generation_error_is_notified_and_human_answer_resolves_it (test_protocol_manual_assistant.ProtocolManualAssistantTests.test_generation_error_is_notified_and_human_answer_resolves_it) ... ok test_late_human_sync_keeps_question_sent_after_that_human_reply (test_protocol_manual_assistant.ProtocolManualAssistantTests.test_late_human_sync_keeps_question_sent_after_that_human_reply) ... ok test_legacy_manual_task_with_exact_trigger_can_verify_reply_after_restart (test_protocol_manual_assistant.ProtocolManualAssistantTests.test_legacy_manual_task_with_exact_trigger_can_verify_reply_after_restart) ... ok test_manual_customer_task_finishes_then_future_safe_message_resumes_auto (test_protocol_manual_assistant.ProtocolManualAssistantTests.test_manual_customer_task_finishes_then_future_safe_message_resumes_auto) ... ok test_manual_media_registers_once_without_an_approvable_draft (test_protocol_manual_assistant.ProtocolManualAssistantTests.test_manual_media_registers_once_without_an_approvable_draft) ... ok test_new_risk_after_manual_completion_creates_new_review_episode (test_protocol_manual_assistant.ProtocolManualAssistantTests.test_new_risk_after_manual_completion_creates_new_review_episode) ... ok test_new_unknown_send_registers_manual_notification_then_only_human_finishes (test_protocol_manual_assistant.ProtocolManualAssistantTests.test_new_unknown_send_registers_manual_notification_then_only_human_finishes) ... ok test_other_account_or_bot_outbound_does_not_finish_manual_task (test_protocol_manual_assistant.ProtocolManualAssistantTests.test_other_account_or_bot_outbound_does_not_finish_manual_task) ... ok test_restart_preserves_manual_episode_and_completes_verified_reply (test_protocol_manual_assistant.ProtocolManualAssistantTests.test_restart_preserves_manual_episode_and_completes_verified_reply) ... ok test_terminal_completion_queue_save_failure_restores_evidence_before_retry (test_protocol_manual_assistant.ProtocolManualAssistantTests.test_terminal_completion_queue_save_failure_restores_evidence_before_retry) ... ok test_terminal_unknown_is_completed_by_new_human_reply_without_replaying_or_altering_journal (test_protocol_manual_assistant.ProtocolManualAssistantTests.test_terminal_unknown_is_completed_by_new_human_reply_without_replaying_or_altering_journal) ... ok test_unconfirmed_ai_draft_echo_cannot_be_used_as_manual_completion (test_protocol_manual_assistant.ProtocolManualAssistantTests.test_unconfirmed_ai_draft_echo_cannot_be_used_as_manual_completion) ... ok test_active_send_evidence_is_never_auto_completed (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_active_send_evidence_is_never_auto_completed) ... ok test_automated_outbound_does_not_complete_pending_review (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_automated_outbound_does_not_complete_pending_review) ... ok test_busy_send_lock_yields_without_error_then_sends_next_round (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_busy_send_lock_yields_without_error_then_sends_next_round) ... ok test_close_stops_coordinator (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_close_stops_coordinator) ... ok test_completion_save_failure_rolls_back_queue_and_can_retry (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_completion_save_failure_rolls_back_queue_and_can_retry) ... ok test_coordination_read_error_cannot_clear_a_registered_review (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_coordination_read_error_cannot_clear_a_registered_review) ... ok test_disabled_coordinator_cannot_override_global_review (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_disabled_coordinator_cannot_override_global_review) ... ok test_human_reply_completes_review_discards_draft_and_keeps_seen (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_human_reply_completes_review_discards_draft_and_keeps_seen) ... ok test_late_phone_sync_does_not_swallow_newer_already_queued_question (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_late_phone_sync_does_not_swallow_newer_already_queued_question) ... ok test_new_inbound_while_old_review_is_pending_keeps_review_and_new_draft (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_new_inbound_while_old_review_is_pending_keeps_review_and_new_draft) ... ok test_new_model_risk_still_requires_a_new_review_after_resumption (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_new_model_risk_still_requires_a_new_review_after_resumption) ... ok test_next_message_resumes_automatic_reply_despite_global_review_mode (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_next_message_resumes_automatic_reply_despite_global_review_mode) ... ok test_old_synced_outbound_and_missing_server_receipt_do_not_complete (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_old_synced_outbound_and_missing_server_receipt_do_not_complete) ... ok test_private_assistant_chat_is_never_auto_replied_to (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_private_assistant_chat_is_never_auto_replied_to) ... ok test_registers_one_review_with_persisted_id_and_trigger (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_registers_one_review_with_persisted_id_and_trigger) ... ok test_restart_reconciles_human_reply_then_keeps_subsequent_customer_message (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_restart_reconciles_human_reply_then_keeps_subsequent_customer_message) ... ok test_selective_review_always_precedes_resumed_global_mode (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_selective_review_always_precedes_resumed_global_mode) ... ok test_uncertain_send_releases_shared_lock_and_preserves_receipt_check (test_protocol_review_assistant.ProtocolReviewAssistantTests.test_uncertain_send_releases_shared_lock_and_preserves_receipt_check) ... ok test_actual_store_late_phone_sync_preserves_newer_question (test_protocol_review_assistant.ProtocolSharedCoordinatorTests.test_actual_store_late_phone_sync_preserves_newer_question) ... ok test_cancel_queue_save_failure_does_not_cancel_existing_review (test_protocol_review_assistant.ProtocolSharedCoordinatorTests.test_cancel_queue_save_failure_does_not_cancel_existing_review) ... ok test_cancel_store_failure_retries_after_restart_before_new_question (test_protocol_review_assistant.ProtocolSharedCoordinatorTests.test_cancel_store_failure_retries_after_restart_before_new_question) ... ok test_cancel_works_after_configuration_is_disabled (test_protocol_review_assistant.ProtocolSharedCoordinatorTests.test_cancel_works_after_configuration_is_disabled) ... ok test_durable_completion_survives_protocol_save_failure_without_new_episode (test_protocol_review_assistant.ProtocolSharedCoordinatorTests.test_durable_completion_survives_protocol_save_failure_without_new_episode) ... ok test_durable_manual_resolution_and_new_risk_get_distinct_episode (test_protocol_review_assistant.ProtocolSharedCoordinatorTests.test_durable_manual_resolution_and_new_risk_get_distinct_episode) ... ok test_explicit_cancel_closes_old_reminder_without_auto_resume (test_protocol_review_assistant.ProtocolSharedCoordinatorTests.test_explicit_cancel_closes_old_reminder_without_auto_resume) ... ok test_explicit_handoff_closes_reminder_and_preserves_evidence (test_protocol_review_assistant.ProtocolSharedCoordinatorTests.test_explicit_handoff_closes_reminder_and_preserves_evidence) ... ok test_local_approval_closes_pending_without_future_global_review_bypass (test_protocol_review_assistant.ProtocolSharedCoordinatorTests.test_local_approval_closes_pending_without_future_global_review_bypass) ... ok test_real_store_bot_receipt_is_not_a_manual_approval (test_protocol_review_assistant.ProtocolSharedCoordinatorTests.test_real_store_bot_receipt_is_not_a_manual_approval) ... ok test_recovered_confirmed_local_approval_closes_old_reminder (test_protocol_review_assistant.ProtocolSharedCoordinatorTests.test_recovered_confirmed_local_approval_closes_old_reminder) ... ok test_foreign_account_task_cannot_be_approved_deleted_or_retried (test_protocol_review_visibility.ProtocolReviewVisibilityTests.test_foreign_account_task_cannot_be_approved_deleted_or_retried) ... ok test_high_risk_reason_available_in_automatic_mode (test_protocol_review_visibility.ProtocolReviewVisibilityTests.test_high_risk_reason_available_in_automatic_mode) ... ok test_media_batch_is_visible_manual_work_without_approvable_draft (test_protocol_review_visibility.ProtocolReviewVisibilityTests.test_media_batch_is_visible_manual_work_without_approvable_draft) ... ok test_next_valid_batch_discards_old_manual_requirement (test_protocol_review_visibility.ProtocolReviewVisibilityTests.test_next_valid_batch_discards_old_manual_requirement) ... ok test_old_saved_review_and_manual_tasks_restore_metadata_only (test_protocol_review_visibility.ProtocolReviewVisibilityTests.test_old_saved_review_and_manual_tasks_restore_metadata_only) ... ok test_overlong_batch_cannot_be_approved_as_a_draft (test_protocol_review_visibility.ProtocolReviewVisibilityTests.test_overlong_batch_cannot_be_approved_as_a_draft) ... ok test_retry_clears_old_metadata_then_rechecks_media_without_sending (test_protocol_review_visibility.ProtocolReviewVisibilityTests.test_retry_clears_old_metadata_then_rechecks_media_without_sending) ... ok test_review_draft_reason_persists_then_explicit_approval_sends_once (test_protocol_review_visibility.ProtocolReviewVisibilityTests.test_review_draft_reason_persists_then_explicit_approval_sends_once) ... ok test_unknown_receipt_cannot_be_approved_or_retried (test_protocol_review_visibility.ProtocolReviewVisibilityTests.test_unknown_receipt_cannot_be_approved_or_retried) ... ok test_database_wide_failure_propagates_without_healthy_claim_or_send (test_protocol_listener_continuity.ProtocolListenerContinuityTests.test_database_wide_failure_propagates_without_healthy_claim_or_send) ... ok test_explicit_pre_send_unavailable_stays_error_and_peers_continue (test_protocol_listener_continuity.ProtocolListenerContinuityTests.test_explicit_pre_send_unavailable_stays_error_and_peers_continue) ... ok test_foreign_account_task_cannot_send_while_current_account_continues (test_protocol_listener_continuity.ProtocolListenerContinuityTests.test_foreign_account_task_cannot_send_while_current_account_continues) ... ok test_generation_error_does_not_stop_another_conversation (test_protocol_listener_continuity.ProtocolListenerContinuityTests.test_generation_error_does_not_stop_another_conversation) ... ok test_malformed_message_row_does_not_drop_valid_rows (test_protocol_listener_continuity.ProtocolListenerContinuityTests.test_malformed_message_row_does_not_drop_valid_rows) ... ok test_malformed_task_timing_does_not_block_peers (test_protocol_listener_continuity.ProtocolListenerContinuityTests.test_malformed_task_timing_does_not_block_peers) ... ok test_media_manual_handling_only_blocks_its_own_conversation (test_protocol_listener_continuity.ProtocolListenerContinuityTests.test_media_manual_handling_only_blocks_its_own_conversation) ... ok test_new_messages_and_contact_notices_cannot_replace_unknown_send (test_protocol_listener_continuity.ProtocolListenerContinuityTests.test_new_messages_and_contact_notices_cannot_replace_unknown_send) ... ok test_pending_review_only_blocks_its_own_conversation (test_protocol_listener_continuity.ProtocolListenerContinuityTests.test_pending_review_only_blocks_its_own_conversation) ... ok test_restart_keeps_unknown_and_failed_tasks_isolated (test_protocol_listener_continuity.ProtocolListenerContinuityTests.test_restart_keeps_unknown_and_failed_tasks_isolated) ... ok test_sending_persistence_error_preserves_no_replay_and_peer_processing (test_protocol_listener_continuity.ProtocolListenerContinuityTests.test_sending_persistence_error_preserves_no_replay_and_peer_processing) ... ok test_task_context_read_error_is_recorded_without_stopping_peers (test_protocol_listener_continuity.ProtocolListenerContinuityTests.test_task_context_read_error_is_recorded_without_stopping_peers) ... ok test_unexpected_sender_exception_is_unknown_not_automatic_retry (test_protocol_listener_continuity.ProtocolListenerContinuityTests.test_unexpected_sender_exception_is_unknown_not_automatic_retry) ... ok test_unknown_receipt_does_not_stop_same_poll_or_future_peer_tasks (test_protocol_listener_continuity.ProtocolListenerContinuityTests.test_unknown_receipt_does_not_stop_same_poll_or_future_peer_tasks) ... ok test_cancel_during_generation_does_not_send (test_native_protocol_pipeline.EngineTests.test_cancel_during_generation_does_not_send) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 根据当前会话生成回复 ok test_crash_in_sending_becomes_uncertain (test_native_protocol_pipeline.EngineTests.test_crash_in_sending_becomes_uncertain) ... [协议收信] 同名客户 · 已加入回复队列 ok test_database_read_failure_never_announces_healthy_listener (test_native_protocol_pipeline.EngineTests.test_database_read_failure_never_announces_healthy_listener) ... ok test_duplicate_event_only_sent_once (test_native_protocol_pipeline.EngineTests.test_duplicate_event_only_sent_once) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 根据当前会话生成回复 [协议处理] 同名客户 · 原账号单聊发送 [协议发送成功] 同名客户 · 服务器消息 999 ok test_manual_reply_during_generation_cancels_send (test_native_protocol_pipeline.EngineTests.test_manual_reply_during_generation_cancels_send) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 根据当前会话生成回复 ok test_media_is_left_for_manual_handling (test_native_protocol_pipeline.EngineTests.test_media_is_left_for_manual_handling) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 当前消息需要人工处理;当前未回复消息包含图片、语音或其他非文本内容,协议版需人工处理 ok test_memory_setting_preserves_only_unanswered_batch_when_disabled (test_native_protocol_pipeline.EngineTests.test_memory_setting_preserves_only_unanswered_batch_when_disabled) ... ok test_model_control_tokens_are_not_sent (test_native_protocol_pipeline.EngineTests.test_model_control_tokens_are_not_sent) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 根据当前会话生成回复 [协议处理] 同名客户 · 模型生成失败,可重试;模型未返回有效文本 ok test_model_error_can_retry_before_send (test_native_protocol_pipeline.EngineTests.test_model_error_can_retry_before_send) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 根据当前会话生成回复 [协议处理] 同名客户 · 模型生成失败,可重试;offline [协议处理] 同名客户 · 根据当前会话生成回复 [协议处理] 同名客户 · 原账号单聊发送 [协议发送成功] 同名客户 · 服务器消息 999 ok test_new_incoming_during_generation_discards_old_answer (test_native_protocol_pipeline.EngineTests.test_new_incoming_during_generation_discards_old_answer) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 根据当前会话生成回复 [协议收信] 同名客户 · 已加入回复队列 ok test_new_message_invalidates_approved_draft (test_native_protocol_pipeline.EngineTests.test_new_message_invalidates_approved_draft) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 根据当前会话生成回复 [协议处理] 同名客户 · 人工审核 [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 根据当前会话生成回复 [协议处理] 同名客户 · 人工审核 ok test_only_current_account_processed (test_native_protocol_pipeline.EngineTests.test_only_current_account_processed) ... ok test_pending_batch_window_is_honored (test_native_protocol_pipeline.EngineTests.test_pending_batch_window_is_honored) ... [协议收信] 同名客户 · 已加入回复队列 ok test_pending_review_and_errors_do_not_show_idle (test_native_protocol_pipeline.EngineTests.test_pending_review_and_errors_do_not_show_idle) ... ok test_progress_callback_failure_does_not_repeat_or_block_send (test_native_protocol_pipeline.EngineTests.test_progress_callback_failure_does_not_repeat_or_block_send) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 根据当前会话生成回复 [协议处理] 同名客户 · 原账号单聊发送 [协议发送成功] 同名客户 · 服务器消息 999 ok test_progress_follows_receive_generate_send_then_waiting (test_native_protocol_pipeline.EngineTests.test_progress_follows_receive_generate_send_then_waiting) ... ok test_ready_flag_alone_cannot_enable_transport (test_native_protocol_pipeline.EngineTests.test_ready_flag_alone_cannot_enable_transport) ... ok test_restart_after_confirmed_journal_clears_pending_without_send (test_native_protocol_pipeline.EngineTests.test_restart_after_confirmed_journal_clears_pending_without_send) ... [协议收信] 同名客户 · 已加入回复队列 ok test_review_requires_approval (test_native_protocol_pipeline.EngineTests.test_review_requires_approval) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 根据当前会话生成回复 [协议处理] 同名客户 · 人工审核 [协议处理] 同名客户 · 原账号单聊发送 [协议发送成功] 同名客户 · 服务器消息 999 ok test_runtime_uses_protocol_engine_without_visual_construction (test_native_protocol_pipeline.EngineTests.test_runtime_uses_protocol_engine_without_visual_construction) ... ok test_same_name_conversations_use_distinct_ids (test_native_protocol_pipeline.EngineTests.test_same_name_conversations_use_distinct_ids) ... [协议收信] 同名客户 · 已加入回复队列 [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 根据当前会话生成回复 [协议处理] 同名客户 · 原账号单聊发送 [协议发送成功] 同名客户 · 服务器消息 999 [协议处理] 同名客户 · 根据当前会话生成回复 [协议处理] 同名客户 · 原账号单聊发送 [协议发送成功] 同名客户 · 服务器消息 999 ok test_stop_during_generation_does_not_send (test_native_protocol_pipeline.EngineTests.test_stop_during_generation_does_not_send) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 根据当前会话生成回复 ok test_text_pipeline_with_native_receipt_and_no_feedback (test_native_protocol_pipeline.EngineTests.test_text_pipeline_with_native_receipt_and_no_feedback) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 根据当前会话生成回复 [协议处理] 同名客户 · 原账号单聊发送 [协议发送成功] 同名客户 · 服务器消息 999 ok test_uncertain_send_is_persisted_and_not_retried (test_native_protocol_pipeline.EngineTests.test_uncertain_send_is_persisted_and_not_retried) ... [协议收信] 同名客户 · 已加入回复队列 [协议处理] 同名客户 · 根据当前会话生成回复 [协议处理] 同名客户 · 原账号单聊发送 [协议处理] 同名客户 · 本会话发送结果待人工核对,其他会话继续监听;timeout ok test_unknown_receipt_isolated_with_healthy_poll_log (test_native_protocol_pipeline.EngineTests.test_unknown_receipt_isolated_with_healthy_poll_log) ... ok test_waiting_progress_and_periodic_read_confirmation_are_throttled (test_native_protocol_pipeline.EngineTests.test_waiting_progress_and_periodic_read_confirmation_are_throttled) ... ok test_cancelled_before_send_does_not_consume_id (test_native_protocol_pipeline.JournalTests.test_cancelled_before_send_does_not_consume_id) ... ok test_changed_payload_same_event_is_blocked (test_native_protocol_pipeline.JournalTests.test_changed_payload_same_event_is_blocked) ... ok test_failure_does_not_automatically_retry (test_native_protocol_pipeline.JournalTests.test_failure_does_not_automatically_retry) ... ok test_invalid_text_rejected (test_native_protocol_pipeline.JournalTests.test_invalid_text_rejected) ... ok test_missing_conversation_blocks_send (test_native_protocol_pipeline.JournalTests.test_missing_conversation_blocks_send) ... ok test_reopen_after_success_never_resends (test_native_protocol_pipeline.JournalTests.test_reopen_after_success_never_resends) ... ok test_success_receipt_and_repeat_returns_saved_result (test_native_protocol_pipeline.JournalTests.test_success_receipt_and_repeat_returns_saved_result) ... ok test_unknown_blocks_retry (test_native_protocol_pipeline.JournalTests.test_unknown_blocks_retry) ... ok test_wrong_account_rejected_before_journaling_or_send (test_native_protocol_pipeline.JournalTests.test_wrong_account_rejected_before_journaling_or_send) ... ok test_explicit_cancel_closes_shared_episode_without_native_io (test_visual_review_assistant.SharedVisualAssistantTests.test_explicit_cancel_closes_shared_episode_without_native_io) ... ok test_explicit_handoff_closes_shared_episode_without_approval (test_visual_review_assistant.SharedVisualAssistantTests.test_explicit_handoff_closes_shared_episode_without_approval) ... ok test_failed_queue_cancel_keeps_shared_episode (test_visual_review_assistant.SharedVisualAssistantTests.test_failed_queue_cancel_keeps_shared_episode) ... ok test_failed_reminder_cancel_is_reported_without_claiming_success (test_visual_review_assistant.SharedVisualAssistantTests.test_failed_reminder_cancel_is_reported_without_claiming_success) ... ok test_real_assistant_conversation_cannot_complete_customer_task (test_visual_review_assistant.SharedVisualAssistantTests.test_real_assistant_conversation_cannot_complete_customer_task) ... ok test_real_failed_send_and_local_persistence_failure_keep_task_until_durable (test_visual_review_assistant.SharedVisualAssistantTests.test_real_failed_send_and_local_persistence_failure_keep_task_until_durable) ... ok test_real_manual_task_without_draft_completes_after_human_reply (test_visual_review_assistant.SharedVisualAssistantTests.test_real_manual_task_without_draft_completes_after_human_reply) ... ok test_real_shared_automated_attempt_is_not_human_reply (test_visual_review_assistant.SharedVisualAssistantTests.test_real_shared_automated_attempt_is_not_human_reply) ... ok test_real_shared_completion_retries_original_episode_after_disk_failure (test_visual_review_assistant.SharedVisualAssistantTests.test_real_shared_completion_retries_original_episode_after_disk_failure) ... ok test_real_shared_human_completion_then_new_risk (test_visual_review_assistant.SharedVisualAssistantTests.test_real_shared_human_completion_then_new_risk) ... ok test_real_shared_local_approval_closes_reminder_without_resuming (test_visual_review_assistant.SharedVisualAssistantTests.test_real_shared_local_approval_closes_reminder_without_resuming) ... ok test_real_terminal_automated_reply_never_completes (test_visual_review_assistant.SharedVisualAssistantTests.test_real_terminal_automated_reply_never_completes) ... ok test_real_terminal_send_requires_distinct_human_and_keeps_original_evidence (test_visual_review_assistant.SharedVisualAssistantTests.test_real_terminal_send_requires_distinct_human_and_keeps_original_evidence) ... ok test_stopped_client_cancel_closes_reminder_in_queue_data_directory (test_visual_review_assistant.SharedVisualAssistantTests.test_stopped_client_cancel_closes_reminder_in_queue_data_directory) ... ok test_active_sending_cancel_or_unrecognized_send_state_cannot_complete (test_visual_review_assistant.VisualAssistantTests.test_active_sending_cancel_or_unrecognized_send_state_cannot_complete) ... ok test_all_ui_attention_states_register_and_notify (test_visual_review_assistant.VisualAssistantTests.test_all_ui_attention_states_register_and_notify) ... ok test_assistant_contact_is_filtered_by_exact_conversation (test_visual_review_assistant.VisualAssistantTests.test_assistant_contact_is_filtered_by_exact_conversation) ... ok test_completed_review_does_not_erase_a_concurrent_replacement (test_visual_review_assistant.VisualAssistantTests.test_completed_review_does_not_erase_a_concurrent_replacement) ... ok test_disabled_config_never_imports_native_or_starts_coordinator (test_visual_review_assistant.VisualAssistantTests.test_disabled_config_never_imports_native_or_starts_coordinator) ... ok test_discarded_draft_marker_is_consumed_once (test_visual_review_assistant.VisualAssistantTests.test_discarded_draft_marker_is_consumed_once) ... ok test_draft_marker_retirement_failure_retains_protection (test_visual_review_assistant.VisualAssistantTests.test_draft_marker_retirement_failure_retains_protection) ... ok test_failed_review_id_save_rolls_back_and_does_not_enqueue (test_visual_review_assistant.VisualAssistantTests.test_failed_review_id_save_rolls_back_and_does_not_enqueue) ... ok test_late_mobile_sync_does_not_hide_new_customer_message (test_visual_review_assistant.VisualAssistantTests.test_late_mobile_sync_does_not_hide_new_customer_message) ... ok test_missing_database_and_cross_account_context_cannot_complete (test_visual_review_assistant.VisualAssistantTests.test_missing_database_and_cross_account_context_cannot_complete) ... ok test_new_customer_message_after_human_reply_starts_fresh_task (test_visual_review_assistant.VisualAssistantTests.test_new_customer_message_after_human_reply_starts_fresh_task) ... ok test_new_database_event_arriving_during_read_is_retained (test_visual_review_assistant.VisualAssistantTests.test_new_database_event_arriving_during_read_is_retained) ... ok test_no_evidence_preserves_review_and_persists_review_id (test_visual_review_assistant.VisualAssistantTests.test_no_evidence_preserves_review_and_persists_review_id) ... ok test_notification_registration_requires_durable_state (test_visual_review_assistant.VisualAssistantTests.test_notification_registration_requires_durable_state) ... ok test_pending_review_is_not_bypassed_by_new_safe_message (test_visual_review_assistant.VisualAssistantTests.test_pending_review_is_not_bypassed_by_new_safe_message) ... ok test_persistence_failure_restores_review_and_old_exchange (test_visual_review_assistant.VisualAssistantTests.test_persistence_failure_restores_review_and_old_exchange) ... ok test_proven_human_reply_discards_old_task_without_approving_or_sending (test_visual_review_assistant.VisualAssistantTests.test_proven_human_reply_discards_old_task_without_approving_or_sending) ... ok test_resumed_skips_blanket_only_and_new_risk_still_requires_review (test_visual_review_assistant.VisualAssistantTests.test_resumed_skips_blanket_only_and_new_risk_still_requires_review) ... ok test_retired_draft_and_review_binding_survive_restart (test_visual_review_assistant.VisualAssistantTests.test_retired_draft_and_review_binding_survive_restart) ... [待回复恢复] 已从磁盘恢复 1 个未完成任务。 [待回复恢复] 已从磁盘恢复 1 个未完成任务。 ok test_retired_draft_only_matches_exact_original_and_verified_identity (test_visual_review_assistant.VisualAssistantTests.test_retired_draft_only_matches_exact_original_and_verified_identity) ... ok test_send_attempt_failure_prevents_dispatch_and_local_completion_keeps_approval (test_visual_review_assistant.VisualAssistantTests.test_send_attempt_failure_prevents_dispatch_and_local_completion_keeps_approval) ... [助理审核] 自动发送留痕失败(OSError),暂缓本次发送;保留人工审核,不猜测人工回复。 ok test_stop_suppresses_read_and_notification (test_visual_review_assistant.VisualAssistantTests.test_stop_suppresses_read_and_notification) ... ok test_terminal_states_require_explicit_human_completion_evidence (test_visual_review_assistant.VisualAssistantTests.test_terminal_states_require_explicit_human_completion_evidence) ... ok test_wrong_account_or_conversation_or_review_evidence_cannot_clear_task (test_visual_review_assistant.VisualAssistantTests.test_wrong_account_or_conversation_or_review_evidence_cannot_clear_task) ... ok test_failed_voice_moves_to_manual_filter_and_cannot_approve_empty_reply (test_review_voice_ui.ReviewVoiceUiTests.test_failed_voice_moves_to_manual_filter_and_cannot_approve_empty_reply) ... ok test_human_completed_event_does_not_increment_ai_sent_count (test_review_voice_ui.ReviewVoiceUiTests.test_human_completed_event_does_not_increment_ai_sent_count) ... ok test_human_completion_log_is_successful_recognition_not_automatic_send (test_review_voice_ui.ReviewVoiceUiTests.test_human_completion_log_is_successful_recognition_not_automatic_send) ... ok test_voice_processing_filter_and_snapshot_do_not_claim_ai_generation_or_human_work (test_review_voice_ui.ReviewVoiceUiTests.test_voice_processing_filter_and_snapshot_do_not_claim_ai_generation_or_human_work) ... ok test_voice_progress_and_failure_logs_keep_distinct_tones (test_review_voice_ui.ReviewVoiceUiTests.test_voice_progress_and_failure_logs_keep_distinct_tones) ... ok test_context_failure_returns_none_and_can_recover (test_database_reply_priority.BackgroundDatabaseTests.test_context_failure_returns_none_and_can_recover) ... ok test_polling_during_retry_cooldown_does_not_extend_it (test_database_reply_priority.BackgroundDatabaseTests.test_polling_during_retry_cooldown_does_not_extend_it) ... ok test_slow_key_setup_does_not_block_and_late_poll_result_is_retained (test_database_reply_priority.BackgroundDatabaseTests.test_slow_key_setup_does_not_block_and_late_poll_result_is_retained) ... ok test_active_task_receives_followup_instead_of_only_merging_tag (test_database_reply_priority.DatabaseDetectionTests.test_active_task_receives_followup_instead_of_only_merging_tag) ... [引擎B] 已登记新消息 → 客户甲 [引擎B] 已登记新消息 → 客户甲 ok test_duplicate_message_and_ambiguous_name_are_not_queued (test_database_reply_priority.DatabaseDetectionTests.test_duplicate_message_and_ambiguous_name_are_not_queued) ... [引擎B] 已登记新消息 → 客户甲 ok test_failed_enqueue_is_retried_without_new_database_row (test_database_reply_priority.DatabaseDetectionTests.test_failed_enqueue_is_retried_without_new_database_row) ... [引擎B] [!] 投递未执行: busy [引擎B] 已登记新消息 → 客户甲 ok test_last_outgoing_is_not_queued_and_failure_changes_health (test_database_reply_priority.DatabaseDetectionTests.test_last_outgoing_is_not_queued_and_failure_changes_health) ... [引擎B] DB 直读失败: unreadable,备用检测继续运行 ok test_accounts_keep_independent_cursors_and_accept_late_writes (test_database_reply_priority.DatabaseFixture.test_accounts_keep_independent_cursors_and_accept_late_writes) ... ok test_closed_database_reports_failure (test_database_reply_priority.DatabaseFixture.test_closed_database_reports_failure) ... ok test_context_has_sender_direction_and_media_placeholder (test_database_reply_priority.DatabaseFixture.test_context_has_sender_direction_and_media_placeholder) ... ok test_cross_thread_reads_and_wal_only_messages (test_database_reply_priority.DatabaseFixture.test_cross_thread_reads_and_wal_only_messages) ... ok test_duplicate_titles_never_select_another_account (test_database_reply_priority.DatabaseFixture.test_duplicate_titles_never_select_another_account) ... ok test_initial_history_boundary_ms_and_new_account (test_database_reply_priority.DatabaseFixture.test_initial_history_boundary_ms_and_new_account) ... ok test_large_batch_and_same_second_insertion_do_not_skip (test_database_reply_priority.DatabaseFixture.test_large_batch_and_same_second_insertion_do_not_skip) ... ok test_schema_failure_does_not_advance_valid_account_cursor (test_database_reply_priority.DatabaseFixture.test_schema_failure_does_not_advance_valid_account_cursor) ... ok test_service_reconnect_preserves_consumed_database_rows (test_database_reply_priority.DatabaseFixture.test_service_reconnect_preserves_consumed_database_rows) ... ok test_actual_generation_uses_database_text_without_clipboard_or_remote_vision (test_database_reply_priority.PriorityReplyTests.test_actual_generation_uses_database_text_without_clipboard_or_remote_vision) ... [档案] 首次遇到该会话,已暂存(2 行可见历史) [档案] 旧会话档案归属无法唯一证明,已保留但不会自动用于当前会话。 [AI] 本次提取的新内容: 客户甲 2026/09/14 10:00:00 你好 [AI] 回复内容: 有什么可以帮您? ok test_ambiguous_or_unverified_database_names_cannot_map_visual_contacts (test_database_reply_priority.PriorityReplyTests.test_ambiguous_or_unverified_database_names_cannot_map_visual_contacts) ... ok test_current_database_context_overrides_stale_pre_copied_text (test_database_reply_priority.PriorityReplyTests.test_current_database_context_overrides_stale_pre_copied_text) ... [档案] 首次遇到该会话,已建档(2 行可见历史) ok test_database_direction_beats_old_visible_outgoing_bubble (test_database_reply_priority.PriorityReplyTests.test_database_direction_beats_old_visible_outgoing_bubble) ... ok test_database_event_merges_into_existing_external_visual_task (test_database_reply_priority.PriorityReplyTests.test_database_event_merges_into_existing_external_visual_task) ... ok test_database_success_never_touches_clipboard_or_geometry (test_database_reply_priority.PriorityReplyTests.test_database_success_never_touches_clipboard_or_geometry) ... ok test_empty_database_uses_copy_fallback (test_database_reply_priority.PriorityReplyTests.test_empty_database_uses_copy_fallback) ... [档案] 首次遇到该会话,已建档(1 行可见历史) ok test_external_label_maps_to_unique_database_task_without_changing_hashes (test_database_reply_priority.PriorityReplyTests.test_external_label_maps_to_unique_database_task_without_changing_hashes) ... ok test_failed_active_task_yields_to_new_customer (test_database_reply_priority.PriorityReplyTests.test_failed_active_task_yields_to_new_customer) ... ok test_followup_invalidates_reply_generated_for_old_message (test_database_reply_priority.PriorityReplyTests.test_followup_invalidates_reply_generated_for_old_message) ... ok test_followup_preserves_inflight_stage_and_wakes_worker (test_database_reply_priority.PriorityReplyTests.test_followup_preserves_inflight_stage_and_wakes_worker) ... ok test_new_message_arriving_before_send_rejects_stale_reply (test_database_reply_priority.PriorityReplyTests.test_new_message_arriving_before_send_rejects_stale_reply) ... ok test_new_task_does_not_bind_foreground_identity (test_database_reply_priority.PriorityReplyTests.test_new_task_does_not_bind_foreground_identity) ... ok test_uncertain_send_is_not_reset_by_followup (test_database_reply_priority.PriorityReplyTests.test_uncertain_send_is_not_reset_by_followup) ... ok test_wrong_title_or_missing_latest_id_does_not_use_database (test_database_reply_priority.PriorityReplyTests.test_wrong_title_or_missing_latest_id_does_not_use_database) ... ok test_bad_rows_do_not_crash_context_or_skip_later_valid_messages (test_database_timestamp_audit.DatabaseTimestampAudit.test_bad_rows_do_not_crash_context_or_skip_later_valid_messages) ... ok test_nonfinite_timestamps_are_not_messages (test_database_timestamp_audit.DatabaseTimestampAudit.test_nonfinite_timestamps_are_not_messages) ... ok test_out_of_range_timestamps_are_not_messages (test_database_timestamp_audit.DatabaseTimestampAudit.test_out_of_range_timestamps_are_not_messages) ... ok test_seconds_and_milliseconds_preserve_chronology (test_database_timestamp_audit.DatabaseTimestampAudit.test_seconds_and_milliseconds_preserve_chronology) ... ok test_a_configured_gateway_takes_the_full_prompt_path (test_reply_safety.BotGatewayPathTest.test_a_configured_gateway_takes_the_full_prompt_path) 配了网关就只走 ai_chat,整串消息原样送过去。 ... ok test_blanket_review_mode_is_reported_as_such (test_reply_safety.BotGatewayPathTest.test_blanket_review_mode_is_reported_as_such) ... ok test_no_rule_hit_reports_an_empty_review_reason (test_reply_safety.BotGatewayPathTest.test_no_rule_hit_reports_an_empty_review_reason) ... ok test_the_client_does_not_run_its_own_best_of_n_behind_a_gateway (test_reply_safety.BotGatewayPathTest.test_the_client_does_not_run_its_own_best_of_n_behind_a_gateway) 并发问几个、谁当裁判,全部由后台的角色编排说了算,网关执行。 ... ok test_the_gateway_is_asked_exactly_once (test_reply_safety.BotGatewayPathTest.test_the_gateway_is_asked_exactly_once) 曾经先调一次退化接口、失败再调一次完整的——同一句话付两遍钱。 ... ok test_the_local_shadow_path_shares_one_task_id_across_both_registrations (test_reply_safety.BotGatewayPathTest.test_the_local_shadow_path_shares_one_task_id_across_both_registrations) 影子裁判要登记两次(生成时一次、评分异步回来再一次)——两次必须共用同一个 ... ok test_the_orchestration_trace_is_recorded (test_reply_safety.BotGatewayPathTest.test_the_orchestration_trace_is_recorded) 选了谁、裁判打了多少分——出事之后要能解释"为什么发的是这句"。 ... ok test_the_recorded_call_reports_which_review_rule_it_tripped (test_reply_safety.BotGatewayPathTest.test_the_recorded_call_reports_which_review_rule_it_tripped) 报回后端的这一行要能说清"这条为什么被拦",不是只有分数没有理由。 ... ok test_without_a_gateway_the_local_plan_still_works (test_reply_safety.BotGatewayPathTest.test_without_a_gateway_the_local_plan_still_works) 开发机上没配网关时,本机单出口那条老路一点没变。 ... ok test_a_trace_is_consumed_once (test_reply_safety.GatewayTraceIsolationTest.test_a_trace_is_consumed_once) 取完即清。留着的话下一条回复会挂上上一条的裁判分。 ... ok test_each_thread_sees_only_its_own_trace (test_reply_safety.GatewayTraceIsolationTest.test_each_thread_sees_only_its_own_trace) ... ok test_cancelled_inflight_task_is_rejected_before_any_send_action (test_reply_safety.ManualPendingCancellationTest.test_cancelled_inflight_task_is_rejected_before_any_send_action) ... ok test_live_manual_delete_removes_state_and_blocks_inflight_recreation (test_reply_safety.ManualPendingCancellationTest.test_live_manual_delete_removes_state_and_blocks_inflight_recreation) ... ok test_manual_delete_protects_task_after_send_dispatch_reservation (test_reply_safety.ManualPendingCancellationTest.test_manual_delete_protects_task_after_send_dispatch_reservation) ... ok test_a_failed_disk_write_rolls_the_approval_back (test_reply_safety.ManualReviewApprovalTest.test_a_failed_disk_write_rolls_the_approval_back) 放行标记只活在内存里是不行的。 ... ok test_a_key_that_left_the_queue_is_reported_missing (test_reply_safety.ManualReviewApprovalTest.test_a_key_that_left_the_queue_is_reported_missing) ... ok test_a_task_that_is_not_awaiting_review_is_reported_not_crashed (test_reply_safety.ManualReviewApprovalTest.test_a_task_that_is_not_awaiting_review_is_reported_not_crashed) ... ok test_an_approved_draft_stops_being_held_by_the_review_gate (test_reply_safety.ManualReviewApprovalTest.test_an_approved_draft_stops_being_held_by_the_review_gate) ... ok test_approval_is_single_use_and_does_not_disable_review_for_later_replies (test_reply_safety.ManualReviewApprovalTest.test_approval_is_single_use_and_does_not_disable_review_for_later_replies) 放行一次不能变成"这个客户从此免审"。 ... ok test_approving_a_draft_clears_the_review_flag_and_requeues_it (test_reply_safety.ManualReviewApprovalTest.test_approving_a_draft_clears_the_review_flag_and_requeues_it) ... ok test_empty_input_is_a_no_op (test_reply_safety.ManualReviewApprovalTest.test_empty_input_is_a_no_op) ... ok test_switching_back_to_auto_send_clears_approval_flags_too (test_reply_safety.ManualReviewApprovalTest.test_switching_back_to_auto_send_clears_approval_flags_too) ... ok test_animated_sticker_frames_keep_one_layout_signature (test_reply_safety.MediaReplyTest.test_animated_sticker_frames_keep_one_layout_signature) ... ok test_confirmed_unread_caption_without_placeholder_still_uses_vision (test_reply_safety.MediaReplyTest.test_confirmed_unread_caption_without_placeholder_still_uses_vision) ... [AI] 本次提取的新内容: 客户甲 10:00:00 帮我看看这个 [AI] 媒体/视觉模式,已截取完整聊天消息区域 (8 bytes) [编排] 未配置模型网关,本次使用本机 ai_config 里的单模型设置。后台的「角色编排」不会生效。 [AI] 回复内容: 我看到了,您想重点确认哪一处? ok test_confirmed_unread_empty_clipboard_uses_type_agnostic_safe_reply (test_reply_safety.MediaReplyTest.test_confirmed_unread_empty_clipboard_uses_type_agnostic_safe_reply) ... [AI] 媒体/视觉模式,已截取完整聊天消息区域 (8 bytes) [AI] 已确认未读但媒体类型未知,使用通用安全追问 [AI] 回复内容: 收到消息,请把重点打字说一下 ok test_dify_vision_query_contains_current_text_and_archive_history (test_reply_safety.MediaReplyTest.test_dify_vision_query_contains_current_text_and_archive_history) ... ok test_empty_clipboard_surface_change_enters_media_fallback (test_reply_safety.MediaReplyTest.test_empty_clipboard_surface_change_enters_media_fallback) ... [会话守护] 当前聊天页出现新内容,检查是否为客户未回复消息... [会话守护] 页面有变化但剪贴板为空,将按非文字消息检查。 [会话守护] 发现客户新消息,先合并连续消息再回复。 ok test_explicit_customer_block_proves_flat_avatar_is_real_chat (test_reply_safety.MediaReplyTest.test_explicit_customer_block_proves_flat_avatar_is_real_chat) ... [AI] 本次提取的新内容: 客户甲 7/29 10:00:00 请问今天下午能挂号吗 [AI] 媒体/视觉模式,已截取完整聊天消息区域 (8 bytes) [AI] 视觉结果与已确认未读冲突,改用可验证内容安全回复 [AI] 回复内容: 可以,我先帮您登记。 ok test_explicit_empty_media_set_does_not_rescan_old_history (test_reply_safety.MediaReplyTest.test_explicit_empty_media_set_does_not_rescan_old_history) ... ok test_explicit_image_uses_safe_reply_when_chat_capture_fails (test_reply_safety.MediaReplyTest.test_explicit_image_uses_safe_reply_when_chat_capture_fails) ... [AI] 本次提取的新内容: 客户甲 10:00:00 [图片] [AI] [!] 聊天消息区域截图失败: capture failed [AI] 视觉不可用,使用对应媒体类型的安全追问 [AI] 回复内容: 图片我收到了,这边暂时没看清具体内容,您想让我重点看哪一处? ok test_first_record_explicit_customer_text_is_still_visually_confirmed (test_reply_safety.MediaReplyTest.test_first_record_explicit_customer_text_is_still_visually_confirmed) ... [AI] 本次提取的新内容: 客户甲 7/29 10:00:00 请问今天下午能挂号吗 [AI] 媒体/视觉模式,已截取完整聊天消息区域 (8 bytes) [AI] 回复内容: 可以的,我先帮您登记需求。 ok test_first_record_visual_failure_never_answers_visible_old_text (test_reply_safety.MediaReplyTest.test_first_record_visual_failure_never_answers_visible_old_text) ... ok test_image_and_text_batch_automatically_uses_mixed_vision (test_reply_safety.MediaReplyTest.test_image_and_text_batch_automatically_uses_mixed_vision) ... [AI] 本次提取的新内容: 客户甲 10:00:00 [图片],这个处方天数改成15天吧 [AI] 媒体/视觉模式,已截取完整聊天消息区域 (8 bytes) [AI] 回复内容: 我看到了,先核对后再告诉您。 ok test_legacy_inflight_state_does_not_invent_an_empty_send_anchor (test_reply_safety.MediaReplyTest.test_legacy_inflight_state_does_not_invent_an_empty_send_anchor) ... [待回复恢复] 已从磁盘恢复 1 个未完成任务。 ok test_media_markers_are_detected_but_unicode_emoji_stays_text (test_reply_safety.MediaReplyTest.test_media_markers_are_detected_but_unicode_emoji_stays_text) ... ok test_message_arriving_during_final_extraction_skips_model (test_reply_safety.MediaReplyTest.test_message_arriving_during_final_extraction_skips_model) ... [回复保护] 最终提取期间又出现新消息,重新开始消息合并等待。 ok test_message_arriving_during_model_call_cancels_stale_reply (test_reply_safety.MediaReplyTest.test_message_arriving_during_model_call_cancels_stale_reply) ... [AI] 本次提取的新内容: 客户甲 10:00:00 [图片],请看一下 [AI] 媒体/视觉模式,已截取完整聊天消息区域 (8 bytes) [回复保护] 模型处理期间又出现新消息,已取消旧回复并重新合并。 ok test_mixed_vision_without_contains_voice_is_rejected (test_reply_safety.MediaReplyTest.test_mixed_vision_without_contains_voice_is_rejected) ... ok test_nested_diagnostic_object_cannot_override_protocol_result (test_reply_safety.MediaReplyTest.test_nested_diagnostic_object_cannot_override_protocol_result) ... ok test_non_json_vision_text_is_never_treated_as_new_message_proof (test_reply_safety.MediaReplyTest.test_non_json_vision_text_is_never_treated_as_new_message_proof) ... ok test_openai_vision_receives_current_text_history_and_chat_screenshot (test_reply_safety.MediaReplyTest.test_openai_vision_receives_current_text_history_and_chat_screenshot) ... ok test_pending_text_is_restored_after_model_or_send_failure (test_reply_safety.MediaReplyTest.test_pending_text_is_restored_after_model_or_send_failure) ... [AI] 已恢复上次未成功发送的待回复内容 [AI] 本次提取的新内容: 客户甲 10:00:00 上一轮尚未成功发送的问题 [AI] 使用文本模式分析聊天记录... [AI] 回复内容: 这次继续回复。 ok test_pending_unread_task_survives_process_restart (test_reply_safety.MediaReplyTest.test_pending_unread_task_survives_process_restart) ... [待回复恢复] 已从磁盘恢复 1 个未完成任务。 ok test_previous_16_byte_pending_key_is_loaded_instead_of_dropped (test_reply_safety.MediaReplyTest.test_previous_16_byte_pending_key_is_loaded_instead_of_dropped) ... [待回复恢复] 已从磁盘恢复 1 个未完成任务。 ok test_pure_voice_never_asks_a_model_to_guess_audio (test_reply_safety.MediaReplyTest.test_pure_voice_never_asks_a_model_to_guess_audio) ... [AI] 本次提取的新内容: 客户甲 10:00:00 [语音] FAIL test_repeated_identical_media_blocks_remain_a_nonempty_delta (test_reply_safety.MediaReplyTest.test_repeated_identical_media_blocks_remain_a_nonempty_delta) ... ok test_screenshot_only_image_type_is_preserved_in_archive (test_reply_safety.MediaReplyTest.test_screenshot_only_image_type_is_preserved_in_archive) ... [AI] 媒体/视觉模式,已截取完整聊天消息区域 (8 bytes) [AI] 回复内容: 图片我看到了,您想重点确认哪一处? ok test_screenshot_only_voice_type_is_preserved_for_safe_archive (test_reply_safety.MediaReplyTest.test_screenshot_only_voice_type_is_preserved_for_safe_archive) ... [AI] 媒体/视觉模式,已截取完整聊天消息区域 (8 bytes) [AI] 回复内容: 这条语音我这边暂时没法准确听清,麻烦您把重点打成文字发我一下。 ok test_second_visual_no_incoming_clears_unconfirmed_unreliable_candidate (test_reply_safety.MediaReplyTest.test_second_visual_no_incoming_clears_unconfirmed_unreliable_candidate) ... [AI] 媒体/视觉模式,已截取完整聊天消息区域 (8 bytes) [AI 页面确认] 纯色头像候选不是客户消息页,已跳过且不会发送。 ok test_second_visual_no_incoming_keeps_confirmed_unread_and_uses_safe_media_reply (test_reply_safety.MediaReplyTest.test_second_visual_no_incoming_keeps_confirmed_unread_and_uses_safe_media_reply) ... [AI] 媒体/视觉模式,已截取完整聊天消息区域 (8 bytes) [AI] 视觉结果与已确认未读冲突,改用可验证内容安全回复 [AI] 回复内容: 收到消息,请把重点打字说一下。 ok test_second_visual_no_incoming_keeps_reliable_text_pending_and_uses_safe_text (test_reply_safety.MediaReplyTest.test_second_visual_no_incoming_keeps_reliable_text_pending_and_uses_safe_text) ... [AI] 本次提取的新内容: 客户甲 10:00:00 帮我看看这个 [AI] 媒体/视觉模式,已截取完整聊天消息区域 (8 bytes) [AI] 视觉结果与已确认未读冲突,改用可验证内容安全回复 [AI] 回复内容: 您想让我重点看哪一处? ok test_selected_caption_falls_back_to_safe_text_when_vision_fails (test_reply_safety.MediaReplyTest.test_selected_caption_falls_back_to_safe_text_when_vision_fails) ... [AI] 本次提取的新内容: 客户甲 10:00:00 帮我看看这个 [AI] 媒体/视觉模式,已截取完整聊天消息区域 (8 bytes) [AI] 视觉不可用,降级为同批可见文字回复 [AI] 回复内容: 您想让我重点看哪一处? ok test_selected_row_detection_flicker_reuses_same_session_cache (test_reply_safety.MediaReplyTest.test_selected_row_detection_flicker_reuses_same_session_cache) ... ok test_selected_row_preview_detects_same_layout_media_replacement (test_reply_safety.MediaReplyTest.test_selected_row_preview_detects_same_layout_media_replacement) ... ok test_selected_row_preview_is_stable_when_row_moves (test_reply_safety.MediaReplyTest.test_selected_row_preview_is_stable_when_row_moves) ... ok test_snapshot_is_committed_only_after_successful_send (test_reply_safety.MediaReplyTest.test_snapshot_is_committed_only_after_successful_send) ... [档案] 增量提取到 2 行新消息(历史上下文由会话档案提供) ok test_unchanged_clipboard_text_is_not_replied_to_again (test_reply_safety.MediaReplyTest.test_unchanged_clipboard_text_is_not_replied_to_again) ... [档案] 剪贴板没有新增文字,将检查是否为非文字消息 ok test_unconfirmed_empty_clipboard_never_sends_generic_media_reply (test_reply_safety.MediaReplyTest.test_unconfirmed_empty_clipboard_never_sends_generic_media_reply) ... [AI] 媒体/视觉模式,已截取完整聊天消息区域 (8 bytes) [AI] 无法确认本轮非文字内容,保留任务稍后重试 ok test_unfinished_merge_deadline_survives_process_restart (test_reply_safety.MediaReplyTest.test_unfinished_merge_deadline_survives_process_restart) ... [待回复恢复] 已从磁盘恢复 1 个未完成任务。 ok test_unknown_flat_avatar_vision_failure_never_uses_generic_fallback (test_reply_safety.MediaReplyTest.test_unknown_flat_avatar_vision_failure_never_uses_generic_fallback) ... [AI] 媒体/视觉模式,已截取完整聊天消息区域 (8 bytes) [AI 页面确认] 尚未确认这是客户消息页,保留任务且不发送兜底话术。 ok test_unknown_visual_result_cannot_guess_untranscribed_voice (test_reply_safety.MediaReplyTest.test_unknown_visual_result_cannot_guess_untranscribed_voice) ... ok test_vision_parser_ignores_analysis_json_before_protocol_result (test_reply_safety.MediaReplyTest.test_vision_parser_ignores_analysis_json_before_protocol_result) ... ok test_vision_parser_uses_last_protocol_object (test_reply_safety.MediaReplyTest.test_vision_parser_uses_last_protocol_object) ... ok test_vision_protocol_conflicts_fail_closed (test_reply_safety.MediaReplyTest.test_vision_protocol_conflicts_fail_closed) ... ok test_visual_failure_does_not_reply_to_stale_clipboard_text (test_reply_safety.MediaReplyTest.test_visual_failure_does_not_reply_to_stale_clipboard_text) ... [AI] 媒体/视觉模式,已截取完整聊天消息区域 (8 bytes) [AI] 视觉失败且剪贴板只有旧文字,保留任务稍后重试 ok test_visual_no_incoming_conflict_never_sends_caption_without_media_warning (test_reply_safety.MediaReplyTest.test_visual_no_incoming_conflict_never_sends_caption_without_media_warning) ... [AI] 本次提取的新内容: 客户甲 10:00:00 帮我看看这个 [AI] 媒体/视觉模式,已截取完整聊天消息区域 (8 bytes) [AI] 视觉结果与已确认未读冲突,改用可验证内容安全回复 [AI] 回复内容: 您想让我重点看哪一处? ok test_voice_control_labels_are_not_treated_as_transcription (test_reply_safety.MediaReplyTest.test_voice_control_labels_are_not_treated_as_transcription) ... ok test_voice_duration_is_not_mistaken_for_transcription (test_reply_safety.MediaReplyTest.test_voice_duration_is_not_mistaken_for_transcription) ... ok test_voice_plus_visible_text_answers_text_without_guessing_audio (test_reply_safety.MediaReplyTest.test_voice_plus_visible_text_answers_text_without_guessing_audio) ... [AI] 本次提取的新内容: 客户甲 10:00:00 [语音] 00:05 明天下午能挂号吗 [AI] 媒体/视觉模式,已截取完整聊天消息区域 (8 bytes) [AI] 回复内容: 明天下午可以,我先帮您登记。 ok test_voice_safety_result_preserves_other_mixed_media_types (test_reply_safety.MediaReplyTest.test_voice_safety_result_preserves_other_mixed_media_types) ... ok test_agent_tail_still_settles_and_clears_the_task (test_reply_safety.NothingLeftToAnswerTextProofTest.test_agent_tail_still_settles_and_clears_the_task) ... ok test_customer_tail_overrides_the_outgoing_bubble_and_keeps_the_task (test_reply_safety.NothingLeftToAnswerTextProofTest.test_customer_tail_overrides_the_outgoing_bubble_and_keeps_the_task) ... ok test_delivered_reply_is_archived_before_answering_the_followup (test_reply_safety.NothingLeftToAnswerTextProofTest.test_delivered_reply_is_archived_before_answering_the_followup) ... ok test_explicit_chat_text_skips_the_extra_extraction (test_reply_safety.NothingLeftToAnswerTextProofTest.test_explicit_chat_text_skips_the_extra_extraction) ... ok test_display_name_waits_until_the_title_matches_the_target (test_reply_safety.PendingDisplayNameBindingTest.test_display_name_waits_until_the_title_matches_the_target) ... ok test_age_question_mismatch_is_repaired (test_reply_safety.ReplyStyleTest.test_age_question_mismatch_is_repaired) ... ok test_casual_tired_message_is_not_redirected_to_hospital (test_reply_safety.ReplyStyleTest.test_casual_tired_message_is_not_redirected_to_hospital) ... ok test_clarification_does_not_ask_customer_to_repeat (test_reply_safety.ReplyStyleTest.test_clarification_does_not_ask_customer_to_repeat) ... ok test_dify_query_marks_latest_message_as_only_target (test_reply_safety.ReplyStyleTest.test_dify_query_marks_latest_message_as_only_target) ... ok test_emergency_reply_keeps_three_short_sentences (test_reply_safety.ReplyStyleTest.test_emergency_reply_keeps_three_short_sentences) ... ok test_extracts_the_real_latest_customer_sentence (test_reply_safety.ReplyStyleTest.test_extracts_the_real_latest_customer_sentence) ... ok test_low_information_customer_turn_never_guesses_phone_mistouch (test_reply_safety.ReplyStyleTest.test_low_information_customer_turn_never_guesses_phone_mistouch) ... ok test_merges_five_consecutive_customer_bubbles_as_one_turn (test_reply_safety.ReplyStyleTest.test_merges_five_consecutive_customer_bubbles_as_one_turn) ... ok test_old_raw_history_does_not_relabel_staff_reply_as_customer (test_reply_safety.ReplyStyleTest.test_old_raw_history_does_not_relabel_staff_reply_as_customer) ... ok test_removes_markdown_canned_closing_and_extra_questions (test_reply_safety.ReplyStyleTest.test_removes_markdown_canned_closing_and_extra_questions) ... ok test_200_percent_dpi_detects_both_resizable_composer_heights (test_reply_safety.SafetyGateTest.test_200_percent_dpi_detects_both_resizable_composer_heights) ... ok test_200_percent_dpi_input_point_is_inside_editor_body (test_reply_safety.SafetyGateTest.test_200_percent_dpi_input_point_is_inside_editor_body) ... ok test_a_baseline_already_holding_the_reply_proves_nothing (test_reply_safety.SafetyGateTest.test_a_baseline_already_holding_the_reply_proves_nothing) 基线里已经有这句话,发送前后长得一样,证明不了任何事。 ... ok test_a_blank_name_hash_falls_back_to_the_strict_avatar_tolerance (test_reply_safety.SafetyGateTest.test_a_blank_name_hash_falls_back_to_the_strict_avatar_tolerance) 名称采不到字时它什么都证明不了,头像必须回到严格容差。 ... ok test_a_broken_autosend_value_falls_back_to_disabled (test_reply_safety.SafetyGateTest.test_a_broken_autosend_value_falls_back_to_disabled) 配置读坏了的时候,宁可什么都不做,也不能拿别人的字去发给客户。 ... ok test_a_clock_jump_backwards_does_not_freeze_the_session_forever (test_reply_safety.SafetyGateTest.test_a_clock_jump_backwards_does_not_freeze_the_session_forever) 墙钟被 NTP 往回校时,标记时间会变成"未来"——不能因此永远跳过。 ... ok test_a_composed_reply_waits_out_the_last_seconds_of_spacing (test_reply_safety.SafetyGateTest.test_a_composed_reply_waits_out_the_last_seconds_of_spacing) 回复已经生成就不能因为还差几秒发送间隔被丢掉,下一轮要从头再调模型。 ... [发送保护] 发送间隔还差 1.0 秒,等完这段再把本条发出去。 ok test_a_customer_followup_does_not_cancel_our_receipt (test_reply_safety.SafetyGateTest.test_a_customer_followup_does_not_cancel_our_receipt) 客户在我们发完后马上又说一句,末条气泡就在左边。 ... ok test_a_customer_image_is_kept_with_the_archived_message (test_reply_safety.SafetyGateTest.test_a_customer_image_is_kept_with_the_archived_message) 企微图片没有可复制文本,档案里只剩「(客户发来图片)」这行占位。 ... ok test_a_different_contact_still_only_establishes_a_baseline (test_reply_safety.SafetyGateTest.test_a_different_contact_still_only_establishes_a_baseline) 名称哈希不同就是另一个人,必须停在建基线,绝不能串聊天。 ... [会话守护] 已建立当前聊天页基线;画面未变化时不会操作鼠标。 ok test_a_dispatched_transaction_keeps_its_draft_untouched (test_reply_safety.SafetyGateTest.test_a_dispatched_transaction_keeps_its_draft_untouched) 已经按过回车的事务归回执核对管,这里清掉再发就是重复发送。 ... ok test_a_far_avatar_under_the_same_name_is_still_a_different_row (test_reply_safety.SafetyGateTest.test_a_far_avatar_under_the_same_name_is_still_a_different_row) 名称相同也不能无条件放行;头像彻底不同仍必须拒绝。 ... ok test_a_findable_task_never_expires_on_a_bad_count (test_reply_safety.SafetyGateTest.test_a_findable_task_never_expires_on_a_bad_count) ... ok test_a_finished_session_releases_the_round_at_once (test_reply_safety.SafetyGateTest.test_a_finished_session_releases_the_round_at_once) 回完就立刻放行,排队的会话不该多等一轮。 ... ok test_a_full_chat_keeps_the_proven_path_first (test_reply_safety.SafetyGateTest.test_a_full_chat_keeps_the_proven_path_first) 消息占满面板时不改动既有顺序,墨迹路径只当兜底。 ... ok test_a_headerless_chat_can_still_prove_the_reply_landed (test_reply_safety.SafetyGateTest.test_a_headerless_chat_can_still_prove_the_reply_landed) ... ok test_a_human_draft_parks_the_session_instead_of_retrying_forever (test_reply_safety.SafetyGateTest.test_a_human_draft_parks_the_session_instead_of_retrying_forever) 这就是用户报的"一直占用进程":拦是拦住了,但每一轮都要重拦一次。 ... ok test_a_human_sentence_still_stops_the_bot_cold (test_reply_safety.SafetyGateTest.test_a_human_sentence_still_stops_the_bot_cold) ... ok test_a_lingering_chat_selection_is_not_a_human_draft (test_reply_safety.SafetyGateTest.test_a_lingering_chat_selection_is_not_a_human_draft) 机器人刚框选复制过聊天记录,那块高亮不会因为点一下空白就消失。 ... ok test_a_login_page_without_a_workspace_locks_the_bot (test_reply_safety.SafetyGateTest.test_a_login_page_without_a_workspace_locks_the_bot) ... [安全验证] 检测到企业微信登录/安全验证二维码,已停止全部自动点击和发送。请用手机企业微信扫码完成验证;监听会等待消息界面恢复。 ok test_a_long_rate_limit_still_leaves_the_task_for_later (test_reply_safety.SafetyGateTest.test_a_long_rate_limit_still_leaves_the_task_for_later) 分钟/小时配额用尽时不能原地干等,必须放行让轮询继续跑。 ... ok test_a_message_taller_than_one_screen_is_scrolled_up_for (test_reply_safety.SafetyGateTest.test_a_message_taller_than_one_screen_is_scrolled_up_for) 满屏正文却没有表头,说明这条消息的开头还在上面,必须往上翻。 ... [剪贴板] 最新一条消息超过一屏,正在向上翻找开头… [剪贴板] 成功提取 23 行聊天记录(共采集 2 屏 / 去重后 23 行) ok test_a_missing_arrival_time_never_breaks_the_queue (test_reply_safety.SafetyGateTest.test_a_missing_arrival_time_never_breaks_the_queue) 旧任务缺少 created_at 时排队不能崩,只能排在最前面等着被收掉。 ... ok test_a_normal_screen_with_headers_never_scrolls (test_reply_safety.SafetyGateTest.test_a_normal_screen_with_headers_never_scrolls) 能看到表头就说明这条消息是完整的,多翻一屏是白白浪费两秒。 ... [剪贴板] 成功提取 17 行聊天记录(共采集 1 屏 / 去重后 17 行) ok test_a_page_without_a_composer_leaves_the_reply_queue (test_reply_safety.SafetyGateTest.test_a_page_without_a_composer_leaves_the_reply_queue) ... [会话过滤] 该会话连续 3 次没有输入框,判定为订阅号/系统号,已移出回复队列,不再重复调用模型。6 小时后会自动复查一次。 ok test_a_payment_qr_sent_into_a_chat_is_not_a_login_page (test_reply_safety.SafetyGateTest.test_a_payment_qr_sent_into_a_chat_is_not_a_login_page) 客户发一张收款码进来,机器人不能就此罢工等人扫码。 ... ok test_a_quiet_chat_reports_no_followup_to_chase (test_reply_safety.SafetyGateTest.test_a_quiet_chat_reports_no_followup_to_chase) ... ok test_a_readable_screen_without_our_reply_frees_the_customer (test_reply_safety.SafetyGateTest.test_a_readable_screen_without_our_reply_frees_the_customer) ... [发送对账] 挂满 600 秒仍无法确认,屏幕上也找不到这句回复,放回队列重新回复。 ok test_a_real_draft_in_a_non_blank_editor_still_wins (test_reply_safety.SafetyGateTest.test_a_real_draft_in_a_non_blank_editor_still_wins) ... ok test_a_real_login_qr_still_stops_everything (test_reply_safety.SafetyGateTest.test_a_real_login_qr_still_stops_everything) ... ok test_a_recovered_copy_rebuilds_the_missing_send_anchor (test_reply_safety.SafetyGateTest.test_a_recovered_copy_rebuilds_the_missing_send_anchor) 带表头的复制文本必须能解析出锚点——这正是发送被卡住的那一步。 ... ok test_a_reopened_row_clears_its_own_strikes (test_reply_safety.SafetyGateTest.test_a_reopened_row_clears_its_own_strikes) 真会话偶尔判错一次,不能因此被误判成订阅号。 ... ok test_a_reordered_row_does_not_cost_everyone_else_the_round (test_reply_safety.SafetyGateTest.test_a_reordered_row_does_not_cost_everyone_else_the_round) 刷屏消息把列表搅乱时,打不开的那个会话不能拖着所有人一起等下一轮。 ... [新消息] 正在处理 row0(坐标: 200, 16) [页面校验] 目标会话本轮打不开,先服务其他未读会话,稍后再回来。 [新消息] 正在处理 row0(坐标: 200, 16) [页面校验] 目标会话本轮打不开,先服务其他未读会话,稍后再回来。 ok test_a_reply_found_on_screen_after_the_deadline_counts_as_sent (test_reply_safety.SafetyGateTest.test_a_reply_found_on_screen_after_the_deadline_counts_as_sent) ... [发送对账] 挂满 600 秒;回复已在屏幕上,判定发送成功。 ok test_a_reply_missing_from_the_screen_is_still_refused (test_reply_safety.SafetyGateTest.test_a_reply_missing_from_the_screen_is_still_refused) 末条气泡不再有否决权,但"屏幕上根本没有这句话"仍然必须判失败。 ... ok test_a_reply_that_never_appeared_is_not_accepted (test_reply_safety.SafetyGateTest.test_a_reply_that_never_appeared_is_not_accepted) ... ok test_a_saved_snapshot_lands_on_disk_and_old_ones_are_pruned (test_reply_safety.SafetyGateTest.test_a_saved_snapshot_lands_on_disk_and_old_ones_are_pruned) ... ok test_a_session_with_no_task_never_blows_up (test_reply_safety.SafetyGateTest.test_a_session_with_no_task_never_blows_up) ... ok test_a_session_without_a_task_never_gets_its_draft_wiped (test_reply_safety.SafetyGateTest.test_a_session_without_a_task_never_gets_its_draft_wiped) ... ok test_a_sparse_chat_tries_the_ink_anchored_drag_first (test_reply_safety.SafetyGateTest.test_a_sparse_chat_tries_the_ink_anchored_drag_first) 消息稀疏时先走墨迹路径,省下两次注定选空的拖拽。 ... ok test_a_sparse_headerless_chat_does_not_trigger_the_search (test_reply_safety.SafetyGateTest.test_a_sparse_headerless_chat_does_not_trigger_the_search) 新会话同样复制不出表头,但它行数很少,不该被当成被截断的长消息。 ... [剪贴板] 成功提取 1 行聊天记录(共采集 1 屏 / 去重后 1 行) ok test_a_stuck_session_stops_blocking_everyone_else (test_reply_safety.SafetyGateTest.test_a_stuck_session_stops_blocking_everyone_else) 真卡住的会话必须到点放行,否则后面排队的客户一起陪葬。 ... [排队] 当前会话已占用 61 秒仍未回完,先放行其他会话,稍后再回来处理它。 ok test_a_subscription_row_is_evicted_from_the_queue (test_reply_safety.SafetyGateTest.test_a_subscription_row_is_evicted_from_the_queue) 指纹分毫不差、但这一行根本不是聊天:再等下去也不会变。 ... [会话过滤] 该会话连续 2 次被判定为非聊天行(订阅号/系统号),已移出回复队列,不再为它扫描列表。6 小时后会自动复查一次。 ok test_a_successful_resume_clears_the_backoff (test_reply_safety.SafetyGateTest.test_a_successful_resume_clears_the_backoff) ... [待回复恢复] 找到已读未回复会话,正在按头像和名称复合指纹重新打开。 ok test_a_task_is_never_judged_before_the_screen_can_catch_up (test_reply_safety.SafetyGateTest.test_a_task_is_never_judged_before_the_screen_can_catch_up) 刚按下回车就断言"屏幕没变=没发出去",会冤枉刚刚发成功的那一条。 ... ok test_a_task_with_no_dispatch_time_is_left_alone (test_reply_safety.SafetyGateTest.test_a_task_with_no_dispatch_time_is_left_alone) ... ok test_a_task_with_no_matching_row_anywhere_expires (test_reply_safety.SafetyGateTest.test_a_task_with_no_matching_row_anywhere_expires) 列表里找不到对应会话的空壳任务不能永远占着队列。 ... [待回复恢复] 该任务连续 8 次在会话列表里找不到对应会话,判定为失效任务并已丢弃;对方再来消息会重新建单。 ok test_a_text_only_exchange_stays_free_of_image_keys (test_reply_safety.SafetyGateTest.test_a_text_only_exchange_stays_free_of_image_keys) ... ok test_a_timed_out_draft_that_trips_a_review_rule_still_waits_for_a_human (test_reply_safety.SafetyGateTest.test_a_timed_out_draft_that_trips_a_review_rule_still_waits_for_a_human) 超时直发不能凌驾于审核规则之上。 ... [发送保护] 输入框里这段字已放置 10.0 分钟,超过设置的 5 分钟,按设置直接发送框里的内容。 [人工审核] 命中审核规则:诊断,回复已填入输入框,等待人工审核发送。 ok test_a_waiting_customer_breaks_the_reconciliation_deadlock (test_reply_safety.SafetyGateTest.test_a_waiting_customer_breaks_the_reconciliation_deadlock) 待核对期间客户还在等 → 放弃旧草稿去回答他,而不是把他晾在那儿。 ... [发送对账] 等了 10 秒,最后一条仍是客户发来的,放弃这条旧草稿,改为回答最新消息。 ok test_a_working_first_drag_never_costs_a_second_one (test_reply_safety.SafetyGateTest.test_a_working_first_drag_never_costs_a_second_one) ... ok test_active_sent_uncommitted_is_reconciled_before_model_call (test_reply_safety.SafetyGateTest.test_active_sent_uncommitted_is_reconciled_before_model_call) ... ok test_actual_staff_name_can_be_proved_by_outgoing_bubble_side (test_reply_safety.SafetyGateTest.test_actual_staff_name_can_be_proved_by_outgoing_bubble_side) ... ok test_actual_staff_name_is_learned_when_configured_nickname_differs (test_reply_safety.SafetyGateTest.test_actual_staff_name_is_learned_when_configured_nickname_differs) ... ok test_ai_page_guard_can_only_open_fixed_message_entry (test_reply_safety.SafetyGateTest.test_ai_page_guard_can_only_open_fixed_message_entry) ... [AI页面守护] 测试: non_message_page / open_messages / 95%(当前是微盘) ok test_ai_page_guard_never_closes_security_verification (test_reply_safety.SafetyGateTest.test_ai_page_guard_never_closes_security_verification) ... [AI页面守护] 测试: security_verification / none / 93%(需要扫码) [安全验证] AI 判断为登录或安全验证页,已禁止自动关闭和发送。 ok test_all_blank_candidates_prefer_the_visible_earlier_process (test_reply_safety.SafetyGateTest.test_all_blank_candidates_prefer_the_visible_earlier_process) 两个窗口都没渲染时(主面板也在托盘里),可见且进程更早的才是主界面。 ... ok test_an_approved_review_draft_actually_presses_enter (test_reply_safety.SafetyGateTest.test_an_approved_review_draft_actually_presses_enter) 放行之后,同一条草稿必须真的发出去。 ... [发送保护] 发送后暂未确认我方消息,已保留本会话并后台对账;不会重复发送,也不会阻塞其他会话。 ok test_an_empty_baseline_never_unlocks_the_raw_anchor (test_reply_safety.SafetyGateTest.test_an_empty_baseline_never_unlocks_the_raw_anchor) 完全读不到聊天内容时不能放行,否则等于取消了重复发送保护。 ... ok test_an_empty_chat_reports_no_ink_instead_of_guessing (test_reply_safety.SafetyGateTest.test_an_empty_chat_reports_no_ink_instead_of_guessing) ... ok test_an_uncertain_editor_never_gets_overwritten (test_reply_safety.SafetyGateTest.test_an_uncertain_editor_never_gets_overwritten) 像素判定拿不准时保持原样保守:宁可不发,也不能覆盖人工输入。 ... ok test_an_unchanged_screen_is_never_taken_as_a_send (test_reply_safety.SafetyGateTest.test_an_unchanged_screen_is_never_taken_as_a_send) ... ok test_an_unchanged_screen_with_our_bubble_last_is_not_called_unsent (test_reply_safety.SafetyGateTest.test_an_unchanged_screen_with_our_bubble_last_is_not_called_unsent) 画面没变却说最后一条是我方发的,两件事对不上,宁可不下"没发出去"。 ... ok test_an_undecidable_screen_is_rechecked_instead_of_rewritten (test_reply_safety.SafetyGateTest.test_an_undecidable_screen_is_rechecked_instead_of_rewritten) 判不出结果时不反复写盘,也不反复框选,就是安静地等下一轮。 ... [发送对账] 发送结果暂未确认,已保留当前任务并后台核对;不会重复发送,也不会阻塞其他会话。 ok test_an_unfinished_scan_keeps_its_progress_without_blocking_unread (test_reply_safety.SafetyGateTest.test_an_unfinished_scan_keeps_its_progress_without_blocking_unread) 翻页扫描没走完要保留进度,但同样不能挡住未读扫描。 ... ok test_an_unfinished_session_keeps_the_round_to_itself (test_reply_safety.SafetyGateTest.test_an_unfinished_session_keeps_the_round_to_itself) 当前会话没回完,本轮不能掉进未读扫描去点开别人。 ... ok test_an_unreadable_screen_never_becomes_a_second_reply (test_reply_safety.SafetyGateTest.test_an_unreadable_screen_never_becomes_a_second_reply) 一个字都读不到时不许推出"没发出去"——那正是连回三条的老路。 ... ok test_an_untouched_chat_proves_the_send_never_landed (test_reply_safety.SafetyGateTest.test_an_untouched_chat_proves_the_send_never_landed) 按回车前后整片聊天区一模一样 → 那一下什么都没发生,可以安全重来。 ... [时钟] 检测到系统时间被回拨(发现于发送对账)。已按“已过很久”重新裁定相关任务,避免超时判断永远不成立而卡死。 [发送对账] 等了 1789704254 秒,聊天区跟按回车前完全一样,判定没发出去,将重新回复。 ok test_an_unwritable_media_dir_never_blocks_the_reply (test_reply_safety.SafetyGateTest.test_an_unwritable_media_dir_never_blocks_the_reply) 留存失败是小事,绝不能因此不回客户。 ... [档案] 会话画面留存失败(不影响回复): 满了 ok test_auto_hiding_chat_scrollbar_never_counts_as_a_new_message (test_reply_safety.SafetyGateTest.test_auto_hiding_chat_scrollbar_never_counts_as_a_new_message) 消息区右缘的滚动条随鼠标进出淡入淡出,绝不能改写聊天画面指纹。 ... [页面校准] 导航栏 136px→320px,会话列表 460px→460px,输入面板顶边 1000px→1000px;会话列表、消息区与输入区域已同步重算。 ok test_auto_mode_holds_a_reply_the_judge_scored_high_risk (test_reply_safety.SafetyGateTest.test_auto_mode_holds_a_reply_the_judge_scored_high_risk) 裁判把这条判成高风险时,就算一条关键词规则都没配,照样要停。 ... [人工审核] 模型裁判评估为高风险,回复已填入输入框,等待人工审核发送。 ok test_auto_mode_holds_a_single_reply_that_trips_a_review_rule (test_reply_safety.SafetyGateTest.test_auto_mode_holds_a_single_reply_that_trips_a_review_rule) 自动发送模式下,命中规则的这一条要单独破例停下来——不用整体切到审核模式。 ... [人工审核] 命中审核规则:诊断,回复已填入输入框,等待人工审核发送。 ok test_auto_mode_still_sends_a_reply_that_trips_nothing (test_reply_safety.SafetyGateTest.test_auto_mode_still_sends_a_reply_that_trips_nothing) 反过来也要证明:没命中任何规则的照常自动发送,功能没有变成"全审"。 ... [发送保护] 发送后暂未确认我方消息,已保留本会话并后台对账;不会重复发送,也不会阻塞其他会话。 ok test_autosend_disabled_keeps_the_draft_untouched_forever (test_reply_safety.SafetyGateTest.test_autosend_disabled_keeps_the_draft_untouched_forever) ... ok test_avatar_anchor_keeps_the_caller_estimate_without_a_lattice (test_reply_safety.SafetyGateTest.test_avatar_anchor_keeps_the_caller_estimate_without_a_lattice) 看不出行距时宁可沿用调用方的估算,不能凭单个色块乱吸附。 ... ok test_avatar_anchor_never_snaps_onto_a_neighbouring_row (test_reply_safety.SafetyGateTest.test_avatar_anchor_never_snaps_onto_a_neighbouring_row) 吸附只能收敛同一行的估算误差,绝不能跨行认错联系人。 ... ok test_avatar_hash_drift_no_longer_swallows_the_first_new_message (test_reply_safety.SafetyGateTest.test_avatar_hash_drift_no_longer_swallows_the_first_new_message) 头像哈希漂 2 位仍是同一个人,第一条消息就必须回复。 ... [会话守护] 当前聊天页出现新内容,检查是否为客户未回复消息... [会话守护] 复制文字未证明有新客户消息,将用视觉确认是否新增媒体。 [会话守护] 发现客户新消息,先合并连续消息再回复。 ok test_badge_and_selected_row_use_the_same_avatar_center (test_reply_safety.SafetyGateTest.test_badge_and_selected_row_use_the_same_avatar_center) ... ok test_badge_offset_error_keeps_the_unread_and_opened_keys_identical (test_reply_safety.SafetyGateTest.test_badge_offset_error_keeps_the_unread_and_opened_keys_identical) 未读徽章按固定偏移推算行中心,偏差不能改写会话键。 ... ok test_blank_child_window_never_wins_over_the_rendered_main_window (test_reply_safety.SafetyGateTest.test_blank_child_window_never_wins_over_the_rendered_main_window) ... [*] 企业微信存在 2 个同类顶层窗口,已挑选真正渲染了主界面的那一个(其余为子进程空壳窗口)。 ok test_block_anchor_tolerates_old_blocks_scrolling_off_screen (test_reply_safety.SafetyGateTest.test_block_anchor_tolerates_old_blocks_scrolling_off_screen) ... ok test_block_anchors_keep_their_own_proven_path (test_reply_safety.SafetyGateTest.test_block_anchors_keep_their_own_proven_path) 有消息块时必须走原来的路径,裸文本只在没有块时兜底。 ... ok test_calibration_gate_keeps_warning_instead_of_going_silent (test_reply_safety.SafetyGateTest.test_calibration_gate_keeps_warning_instead_of_going_silent) 闸门关闭 = 自动回复完全停摆,绝不能只吭一声就静默。 ... ok test_center_modal_close_button_is_detected (test_reply_safety.SafetyGateTest.test_center_modal_close_button_is_detected) ... ok test_chat_bubble_glyph_is_not_treated_as_modal_close (test_reply_safety.SafetyGateTest.test_chat_bubble_glyph_is_not_treated_as_modal_close) ... ok test_chat_capture_still_covers_the_full_outgoing_bubble (test_reply_safety.SafetyGateTest.test_chat_capture_still_covers_the_full_outgoing_bubble) 自己的气泡右缘紧贴滚动条,截图裁剪区不能为了避开滚动条把它切掉。 ... [页面校准] 导航栏 136px→320px,会话列表 460px→460px,输入面板顶边 1000px→1000px;会话列表、消息区与输入区域已同步重算。 ok test_chat_pane_right_detects_sidebar_divider (test_reply_safety.SafetyGateTest.test_chat_pane_right_detects_sidebar_divider) 右侧工具栏展开时,靠纵贯分隔线找到聊天面板右缘。 ... ok test_clearing_the_hold_removes_both_marks (test_reply_safety.SafetyGateTest.test_clearing_the_hold_removes_both_marks) ... ok test_click_can_reopen_flat_avatar_pending_for_visual_confirmation (test_reply_safety.SafetyGateTest.test_click_can_reopen_flat_avatar_pending_for_visual_confirmation) ... ok test_click_fails_closed_when_selected_fingerprint_cannot_be_read (test_reply_safety.SafetyGateTest.test_click_fails_closed_when_selected_fingerprint_cannot_be_read) ... [页面校验] 会话列表发生变化,实际打开对象与目标不一致,已停止后续发送。 ok test_click_ignores_one_transient_post_click_navigation_frame (test_reply_safety.SafetyGateTest.test_click_ignores_one_transient_post_click_navigation_frame) ... ok test_click_relocates_unread_by_fingerprint_before_acting (test_reply_safety.SafetyGateTest.test_click_relocates_unread_by_fingerprint_before_acting) ... ok test_click_two_nav_misses_accepts_raw_target_with_chat_evidence (test_reply_safety.SafetyGateTest.test_click_two_nav_misses_accepts_raw_target_with_chat_evidence) ... [页面校验] 导航选中取色不稳定,但目标会话、标题和聊天区均已确认。 ok test_click_two_nav_misses_without_raw_selected_row_proves_page_exit (test_reply_safety.SafetyGateTest.test_click_two_nav_misses_without_raw_selected_row_proves_page_exit) ... [页面校验] 点击后导航与目标选中行均消失,已确认离开消息页。 ok test_close_avatars_with_different_names_never_match (test_reply_safety.SafetyGateTest.test_close_avatars_with_different_names_never_match) 现场最接近的一对不同联系人(头像仅差 10 位)必须继续被分开。 ... ok test_completed_ordinary_scan_switches_to_hidden_unread_group (test_reply_safety.SafetyGateTest.test_completed_ordinary_scan_switches_to_hidden_unread_group) ... [未读扫描] 当前可视区没有客户红点,开始从列表顶部逐页查找未置顶未读… ok test_composer_border_and_window_backdrop_never_fake_a_draft (test_reply_safety.SafetyGateTest.test_composer_border_and_window_backdrop_never_fake_a_draft) ... ok test_composer_found_despite_wide_content_edge_in_chat (test_reply_safety.SafetyGateTest.test_composer_found_despite_wide_content_edge_in_chat) 聊天区中部的全宽横边不再让分隔线检测放弃(用户实机截图场景)。 ... ok test_composer_scan_is_bounded_inside_chat_pane (test_reply_safety.SafetyGateTest.test_composer_scan_is_bounded_inside_chat_pane) 右侧工具栏内容不再干扰输入区分隔线检测。 ... ok test_confirmed_unread_pending_older_than_24_hours_is_restored (test_reply_safety.SafetyGateTest.test_confirmed_unread_pending_older_than_24_hours_is_restored) ... [待回复恢复] 已从磁盘恢复 1 个未完成任务。 ok test_cross_monitor_window_is_detected_even_when_its_center_monitor_is_valid (test_reply_safety.SafetyGateTest.test_cross_monitor_window_is_detected_even_when_its_center_monitor_is_valid) The field failure spans a 200% laptop and a 100% external panel. ... ok test_cross_monitor_window_is_resized_entirely_inside_primary_work_area (test_reply_safety.SafetyGateTest.test_cross_monitor_window_is_resized_entirely_inside_primary_work_area) ... ok test_ctrl_enter_accepts_verified_square_avatar_raw_fingerprint_once (test_reply_safety.SafetyGateTest.test_ctrl_enter_accepts_verified_square_avatar_raw_fingerprint_once) ... [发送兼容] 检测到 Enter 仅保留草稿,改用 Ctrl+Enter 发送。 ok test_ctrl_enter_is_used_only_after_retained_draft_is_proven (test_reply_safety.SafetyGateTest.test_ctrl_enter_is_used_only_after_retained_draft_is_proven) ... ok test_ctrl_enter_persist_failure_does_not_lock_future_recovery (test_reply_safety.SafetyGateTest.test_ctrl_enter_persist_failure_does_not_lock_future_recovery) ... ok test_ctrl_enter_stops_immediately_when_human_has_taken_over (test_reply_safety.SafetyGateTest.test_ctrl_enter_stops_immediately_when_human_has_taken_over) ... ok test_customer_echoing_an_old_assistant_phrase_is_still_pending (test_reply_safety.SafetyGateTest.test_customer_echoing_an_old_assistant_phrase_is_still_pending) ... ok test_date_bearing_agent_header_is_not_treated_as_customer_message (test_reply_safety.SafetyGateTest.test_date_bearing_agent_header_is_not_treated_as_customer_message) ... ok test_deep_unread_resume_is_not_cancelled_by_scan_cooldown (test_reply_safety.SafetyGateTest.test_deep_unread_resume_is_not_cancelled_by_scan_cooldown) A paused forward scan must continue while the global unread still exists. ... [未读扫描] 继续从上轮停留位置向下查找未置顶未读… [未读扫描] 已扫到列表底部,本轮没有找到可回复的客户未读。 ok test_deep_unread_scan_resumes_after_time_budget_instead_of_restarting (test_reply_safety.SafetyGateTest.test_deep_unread_scan_resumes_after_time_budget_instead_of_restarting) ... [未读扫描] 当前可视区没有客户红点,开始从列表顶部逐页查找未置顶未读… [未读扫描] 列表较长,本轮已达到 45 秒安全扫描上限;下轮从当前位置继续。 [未读扫描] 继续从上轮停留位置向下查找未置顶未读… [未读扫描] 已扫到列表底部,本轮没有找到可回复的客户未读。 ok test_delayed_copy_marker_never_claims_human_draft_is_empty (test_reply_safety.SafetyGateTest.test_delayed_copy_marker_never_claims_human_draft_is_empty) ... ok test_dense_chat_text_is_not_a_login_qr (test_reply_safety.SafetyGateTest.test_dense_chat_text_is_not_a_login_qr) 现场(2026-07-31 14:04):一条带表情的长广告消息让机器人整个停机。 ... ok test_dify_ui_guard_uploads_image_before_chat_message (test_reply_safety.SafetyGateTest.test_dify_ui_guard_uploads_image_before_chat_message) ... ok test_dimmed_background_is_recognised_as_modal_scrim (test_reply_safety.SafetyGateTest.test_dimmed_background_is_recognised_as_modal_scrim) ... ok test_dynamic_navigation_width_supports_narrow_and_wide_sidebars (test_reply_safety.SafetyGateTest.test_dynamic_navigation_width_supports_narrow_and_wide_sidebars) ... ok test_editing_the_draft_restarts_the_autosend_timer (test_reply_safety.SafetyGateTest.test_editing_the_draft_restarts_the_autosend_timer) 人把草稿改了就是另一段话,不能带着上一段的计时直接发出去。 ... ok test_empty_editor_requires_visual_blank_evidence (test_reply_safety.SafetyGateTest.test_empty_editor_requires_visual_blank_evidence) ... ok test_enter_without_visible_receipt_never_commits_or_clears (test_reply_safety.SafetyGateTest.test_enter_without_visible_receipt_never_commits_or_clears) ... [发送保护] 发送后暂未确认我方消息,已保留本会话并后台对账;不会重复发送,也不会阻塞其他会话。 ok test_expanded_right_toolbar_is_excluded_from_empty_editor_vision (test_reply_safety.SafetyGateTest.test_expanded_right_toolbar_is_excluded_from_empty_editor_vision) 200% DPI field evidence must stop at the detected chat divider. ... ok test_failed_composer_redetection_invalidates_every_chat_reader (test_reply_safety.SafetyGateTest.test_failed_composer_redetection_invalidates_every_chat_reader) ... [剪贴板] 聊天区域边界尚未可靠识别,已取消提取。 ok test_failed_reopen_does_not_consume_the_polling_round (test_reply_safety.SafetyGateTest.test_failed_reopen_does_not_consume_the_polling_round) ... [待回复恢复] 找到已读未回复会话,正在按头像和名称复合指纹重新打开。 ok test_filtered_unread_list_uses_avatar_row_and_name_without_red_dot (test_reply_safety.SafetyGateTest.test_filtered_unread_list_uses_avatar_row_and_name_without_red_dot) ... ok test_filtered_unread_row_may_disappear_only_after_exact_title_proof (test_reply_safety.SafetyGateTest.test_filtered_unread_row_may_disappear_only_after_exact_title_proof) ... [页面校验] 未读行点击后已从筛选列表消失,聊天标题逐字身份校验通过。 ok test_final_enter_gate_uses_detected_chat_pane_right (test_reply_safety.SafetyGateTest.test_final_enter_gate_uses_detected_chat_pane_right) Regression: an expanded customer panel used to fake a resize forever. ... ok test_flat_fingerprint_mismatch_is_not_reclassified_as_system_entry (test_reply_safety.SafetyGateTest.test_flat_fingerprint_mismatch_is_not_reclassified_as_system_entry) A row-render mismatch must retry, never permanently blacklist a contact. ... [新消息] 正在处理 row0(坐标: 200, 132) [页面校验] 目标会话本轮打不开,先服务其他未读会话,稍后再回来。 [新消息] 正在处理 row0(坐标: 200, 132) [页面校验] 目标会话本轮打不开,先服务其他未读会话,稍后再回来。 [新消息] 正在处理 row0(坐标: 200, 132) [页面校验] 目标会话本轮打不开,先服务其他未读会话,稍后再回来。 [新消息] 正在处理 row0(坐标: 200, 132) [页面校验] 目标会话本轮打不开,先服务其他未读会话,稍后再回来。 [新消息] 正在处理 row0(坐标: 200, 132) [页面校验] 目标会话本轮打不开,先服务其他未读会话,稍后再回来。 ok test_flat_real_row0_same_open_title_enters_visual_reply_flow (test_reply_safety.SafetyGateTest.test_flat_real_row0_same_open_title_enters_visual_reply_flow) A selected real chat can keep the same title when its unread row is clicked. ... [新消息] 正在处理 row0(坐标: 200, 132) [完成] 回复完成,红点已消失 → row0 ok test_flat_system_entry_clears_the_preclick_pending_reservation (test_reply_safety.SafetyGateTest.test_flat_system_entry_clears_the_preclick_pending_reservation) ... [新消息] 正在处理 row0(坐标: 200, 148) [会话识别] 连续两帧确认候选离开消息页,已排除系统入口并继续扫描。 ok test_flat_text_avatar_is_admitted_only_as_visual_proof_candidate (test_reply_safety.SafetyGateTest.test_flat_text_avatar_is_admitted_only_as_visual_proof_candidate) ... [会话识别] 检测到未读纯色文字头像候选,将先确认消息页与会话身份再回复。 ok test_followup_detection_anchors_latest_same_text_reply (test_reply_safety.SafetyGateTest.test_followup_detection_anchors_latest_same_text_reply) ... ok test_full_business_page_returns_to_messages_without_blind_escape (test_reply_safety.SafetyGateTest.test_full_business_page_returns_to_messages_without_blind_escape) ... ok test_full_selected_fingerprint_overrides_title_render_hash_drift (test_reply_safety.SafetyGateTest.test_full_selected_fingerprint_overrides_title_render_hash_drift) ... [会话校验] 标题发生渲染变化,已通过头像和名称复合指纹确认仍是原会话。 ok test_generate_reply_passes_archive_history_and_stages_whole_batch (test_reply_safety.SafetyGateTest.test_generate_reply_passes_archive_history_and_stages_whole_batch) ... [AI] 会话档案提供历史上下文 2 条 [AI] 本次提取的新内容: 客户甲 7/29 10:00:01 第一段 客户甲 7/29 10:00:08 第二段 客户甲 7/29 10:00:18 第三段 [AI] 使用文本模式分析聊天记录... [AI] 回复内容: 统一回复 ok test_global_unread_signature_follows_located_band (test_reply_safety.SafetyGateTest.test_global_unread_signature_follows_located_band) ... [导航定位] “消息”入口不在默认位置,已按文字识别定位到 y 264~304px。 [导航定位] “消息”入口不在默认位置,已按文字识别定位到 y 264~304px。 ok test_group_member_echo_cannot_be_mistaken_for_our_reply (test_reply_safety.SafetyGateTest.test_group_member_echo_cannot_be_mistaken_for_our_reply) ... ok test_hidden_unread_is_found_on_third_scanned_page (test_reply_safety.SafetyGateTest.test_hidden_unread_is_found_on_third_scanned_page) ... [未读扫描] 当前可视区没有客户红点,开始从列表顶部逐页查找未置顶未读… [未读扫描] 在第 3 页找到客户未读。 ok test_human_draft_is_preserved_and_enter_is_never_pressed (test_reply_safety.SafetyGateTest.test_human_draft_is_preserved_and_enter_is_never_pressed) ... [发送保护] 检测到人工草稿,已保留原内容并取消自动发送。 ok test_incomplete_paste_is_never_sent (test_reply_safety.SafetyGateTest.test_incomplete_paste_is_never_sent) ... [发送保护] 已清除本次未完整写入的自动回复草稿。 [发送保护] 回复未能完整写入聊天输入框,已禁止按下发送键。 ok test_independent_wecom_document_window_is_not_force_closed (test_reply_safety.SafetyGateTest.test_independent_wecom_document_window_is_not_force_closed) ... ok test_input_focus_retries_a_second_visual_editor_point (test_reply_safety.SafetyGateTest.test_input_focus_retries_a_second_visual_editor_point) ... ok test_internal_modal_is_closed_with_escape_before_clicking_x (test_reply_safety.SafetyGateTest.test_internal_modal_is_closed_with_escape_before_clicking_x) ... [页面清理] 测试检测到阻塞弹窗,已用 Esc 自动关闭。 ok test_invalid_session_geometry_never_scrolls_mouse (test_reply_safety.SafetyGateTest.test_invalid_session_geometry_never_scrolls_mouse) ... [未读扫描] 会话列表几何无效,已禁止窗口外滚动。 [未读扫描] 会话列表几何无效,已禁止窗口外翻页。 ok test_last_round_wording_is_still_recognised_as_ours (test_reply_safety.SafetyGateTest.test_last_round_wording_is_still_recognised_as_ours) 模型每轮换一种说法,只比对新回复就永远认不出框里那句是自己写的。 ... ok test_layout_change_after_paste_keeps_draft_and_staged_reply (test_reply_safety.SafetyGateTest.test_layout_change_after_paste_keeps_draft_and_staged_reply) ... [发送保护] 按 Enter 前窗口布局发生变化,已保留自动草稿和已生成回复,稳定后自动续发。 ok test_layout_guard_accepts_one_normalized_semantic_layout (test_reply_safety.SafetyGateTest.test_layout_guard_accepts_one_normalized_semantic_layout) ... ok test_layout_guard_rejects_impossible_or_ambiguous_geometry (test_reply_safety.SafetyGateTest.test_layout_guard_rejects_impossible_or_ambiguous_geometry) ... ok test_layout_rebase_distinguishes_resize_from_appended_message (test_reply_safety.SafetyGateTest.test_layout_rebase_distinguishes_resize_from_appended_message) ... [视觉重定位] 窗口布局已稳定,聊天文字未新增;沿用已生成回复继续发送。 ok test_legacy_archive_is_moved_once_after_composite_identity_is_known (test_reply_safety.SafetyGateTest.test_legacy_archive_is_moved_once_after_composite_identity_is_known) ... [档案] 已将旧版会话档案一次性迁移到新版复合会话键。 ok test_legacy_archive_is_not_migrated_when_customer_name_does_not_match (test_reply_safety.SafetyGateTest.test_legacy_archive_is_not_migrated_when_customer_name_does_not_match) ... [档案] 旧会话档案归属无法唯一证明,已保留但不会自动用于当前会话。 ok test_legacy_archive_with_another_customer_in_history_is_never_migrated (test_reply_safety.SafetyGateTest.test_legacy_archive_with_another_customer_in_history_is_never_migrated) ... [档案] 旧会话档案归属无法唯一证明,已保留但不会自动用于当前会话。 ok test_legacy_pending_identity_cannot_rebind_from_a_full_selected_row (test_reply_safety.SafetyGateTest.test_legacy_pending_identity_cannot_rebind_from_a_full_selected_row) ... ok test_legacy_uncertain_task_yields_to_a_proven_new_customer_turn (test_reply_safety.SafetyGateTest.test_legacy_uncertain_task_yields_to_a_proven_new_customer_turn) ... [发送对账] 检测到客户后续新消息,已放弃结果不明的旧草稿并重新合并;旧回复不会重发。 ok test_login_verification_child_window_is_never_closed (test_reply_safety.SafetyGateTest.test_login_verification_child_window_is_never_closed) ... ok test_lone_hidden_window_is_kept_without_probing_pixels (test_reply_safety.SafetyGateTest.test_lone_hidden_window_is_kept_without_probing_pixels) 主面板收进托盘时只有一个候选,必须原样返回,不能因为“截图是黑的”被否掉。 ... ok test_low_confidence_frame_never_revokes_a_confirmed_navigation_width (test_reply_safety.SafetyGateTest.test_low_confidence_frame_never_revokes_a_confirmed_navigation_width) 置信度不足时沿用已生效宽度,因此不能撤销既有的确认结论。 ... ok test_marking_batch_ready_clears_persisted_merge_deadline (test_reply_safety.SafetyGateTest.test_marking_batch_ready_clears_persisted_merge_deadline) ... ok test_message_batch_aborts_when_chat_identity_changes (test_reply_safety.SafetyGateTest.test_message_batch_aborts_when_chat_identity_changes) ... [消息合并] 开始收集本会话 0 秒内的连续消息… [消息合并] 等待期间聊天对象发生变化,取消本次回复。 ok test_message_batch_aborts_when_same_title_switches_to_another_session (test_reply_safety.SafetyGateTest.test_message_batch_aborts_when_same_title_switches_to_another_session) A same-title manual switch must not contaminate the original pending batch. ... [消息合并] 当前选中会话指纹已变化,取消本次合并与回复。 ok test_message_batch_accepts_title_render_drift_for_same_full_session (test_reply_safety.SafetyGateTest.test_message_batch_accepts_title_render_drift_for_same_full_session) ... [会话校验] 标题发生渲染变化,已通过头像和名称复合指纹确认仍是原会话。 [消息合并] 收集完成(期间检测到 0 次消息画面更新),将只发起 1 次模型请求。 ok test_message_batch_collects_updates_then_allows_one_request (test_reply_safety.SafetyGateTest.test_message_batch_collects_updates_then_allows_one_request) ... [消息合并] 开始收集本会话 0 秒内的连续消息… [消息合并] 收集完成(期间检测到 0 次消息画面更新),将只发起 1 次模型请求。 ok test_message_batch_retry_keeps_original_persisted_deadline (test_reply_safety.SafetyGateTest.test_message_batch_retry_keeps_original_persisted_deadline) A transient retry must wait only the original window's remainder. ... [消息合并] 开始收集本会话 7 秒内的连续消息… [消息合并] 继续上次合并窗口,剩余约 0 秒… ok test_message_nav_band_falls_back_without_wide_text_column (test_reply_safety.SafetyGateTest.test_message_nav_band_falls_back_without_wide_text_column) 窄图标栏 / 找不到导航分界时回退旧的固定位置,不加载 OCR。 ... ok test_message_nav_band_located_by_text_when_not_first (test_reply_safety.SafetyGateTest.test_message_nav_band_located_by_text_when_not_first) “消息”上方有个人资料块时,靠 OCR 文字定位它的行。 ... [导航定位] “消息”入口不在默认位置,已按文字识别定位到 y 264~300px。 ok test_message_nav_selected_uses_located_band (test_reply_safety.SafetyGateTest.test_message_nav_selected_uses_located_band) 选中态校验跟随动态定位的“消息”行,而不是固定 y 65~105。 ... [导航定位] “消息”入口不在默认位置,已按文字识别定位到 y 264~304px。 [导航定位] “消息”入口不在默认位置,已按文字识别定位到 y 264~304px。 ok test_message_page_refreshes_geometry_after_wide_sidebar_opens (test_reply_safety.SafetyGateTest.test_message_page_refreshes_geometry_after_wide_sidebar_opens) ... [页面校准] 导航栏 136px→320px,会话列表 460px→460px,输入面板顶边 1000px→1000px;会话列表、消息区与输入区域已同步重算。 ok test_message_workspace_accepts_sparse_200_percent_dpi_highlight (test_reply_safety.SafetyGateTest.test_message_workspace_accepts_sparse_200_percent_dpi_highlight) Real 200% DPI rounded highlights expose only about 11% blue pixels. ... ok test_message_workspace_uses_selected_navigation_state (test_reply_safety.SafetyGateTest.test_message_workspace_uses_selected_navigation_state) ... ok test_minimum_send_interval_is_enforced (test_reply_safety.SafetyGateTest.test_minimum_send_interval_is_enforced) ... ok test_missing_or_malformed_legacy_anchor_never_confirms_old_reply (test_reply_safety.SafetyGateTest.test_missing_or_malformed_legacy_anchor_never_confirms_old_reply) ... [发送对账] 发送结果暂未确认,已保留当前任务并后台核对;不会重复发送,也不会阻塞其他会话。 ok test_mixed_legacy_and_composite_keys_never_match_by_avatar_only (test_reply_safety.SafetyGateTest.test_mixed_legacy_and_composite_keys_never_match_by_avatar_only) ... ok test_navigation_geometry_is_committed_before_a_chat_composer_exists (test_reply_safety.SafetyGateTest.test_navigation_geometry_is_committed_before_a_chat_composer_exists) 消息首页没有选中会话时也必须先校准列表,才能找到并打开未读客户。 ... [几何刷新] 已先按视觉更新导航和会话列表;当前尚未打开可回复会话,输入区将在打开客户后继续识别。 ok test_navigation_width_inference_accepts_custom_band (test_reply_safety.SafetyGateTest.test_navigation_width_inference_accepts_custom_band) ... ok test_new_customer_content_drops_the_hold_and_re_evaluates (test_reply_safety.SafetyGateTest.test_new_customer_content_drops_the_hold_and_re_evaluates) 客户又说话了就重新判一次:草稿可能已经被人发出去或删掉了。 ... ok test_new_same_text_outgoing_block_confirms_send (test_reply_safety.SafetyGateTest.test_new_same_text_outgoing_block_confirms_send) ... ok test_no_global_unread_does_not_scroll_the_list (test_reply_safety.SafetyGateTest.test_no_global_unread_does_not_scroll_the_list) ... ok test_non_message_page_is_never_treated_as_internal_modal (test_reply_safety.SafetyGateTest.test_non_message_page_is_never_treated_as_internal_modal) ... ok test_normal_bright_page_is_not_a_modal_scrim (test_reply_safety.SafetyGateTest.test_normal_bright_page_is_not_a_modal_scrim) ... ok test_normal_navigation_prevents_false_positive (test_reply_safety.SafetyGateTest.test_normal_navigation_prevents_false_positive) 主界面还在时不停机。这道判断已从像素判据搬到 _security_gate_visible: ... ok test_offscreen_dispatched_head_never_blocks_normal_pending (test_reply_safety.SafetyGateTest.test_offscreen_dispatched_head_never_blocks_normal_pending) ... ok test_offscreen_uncertain_head_never_starts_deep_scan (test_reply_safety.SafetyGateTest.test_offscreen_uncertain_head_never_starts_deep_scan) ... ok test_old_same_text_bubble_cannot_confirm_unchanged_transaction (test_reply_safety.SafetyGateTest.test_old_same_text_bubble_cannot_confirm_unchanged_transaction) ... ok test_old_same_text_plus_new_customer_message_cannot_confirm_send (test_reply_safety.SafetyGateTest.test_old_same_text_plus_new_customer_message_cannot_confirm_send) ... ok test_one_bad_frame_never_silences_a_real_contact (test_reply_safety.SafetyGateTest.test_one_bad_frame_never_silences_a_real_contact) 单帧没渲染完不能把真客户静默移出队列。 ... ok test_open_customer_recaptures_geometry_before_composer_filter (test_reply_safety.SafetyGateTest.test_open_customer_recaptures_geometry_before_composer_filter) ... ok test_open_messages_clicks_located_band_center (test_reply_safety.SafetyGateTest.test_open_messages_clicks_located_band_center) ... [导航定位] “消息”入口不在默认位置,已按文字识别定位到 y 400~480px。 [页面清理] 测试:已返回“消息”页面并通过选中态校验。 ok test_open_messages_uses_safe_message_row_in_wide_navigation (test_reply_safety.SafetyGateTest.test_open_messages_uses_safe_message_row_in_wide_navigation) ... [页面清理] 测试:已返回“消息”页面并通过选中态校验。 ok test_open_unread_group_requires_two_post_click_frames (test_reply_safety.SafetyGateTest.test_open_unread_group_requires_two_post_click_frames) ... ok test_our_own_abandoned_draft_is_cleared_and_resent (test_reply_safety.SafetyGateTest.test_our_own_abandoned_draft_is_cleared_and_resent) ... ok test_our_own_last_bubble_settles_the_task_as_sent (test_reply_safety.SafetyGateTest.test_our_own_last_bubble_settles_the_task_as_sent) ... ok test_page_restore_keeps_pending_and_next_poll_reopens_it (test_reply_safety.SafetyGateTest.test_page_restore_keeps_pending_and_next_poll_reopens_it) ... [页面托管] 当前选中的不是“消息”,正在自动恢复工作页。 ok test_pending_persist_failure_prevents_unread_click (test_reply_safety.SafetyGateTest.test_pending_persist_failure_prevents_unread_click) Never consume the unread badge when its recovery task is not durable. ... [待回复恢复] 未读任务无法落盘,已禁止点击以避免丢失消息。 ok test_pending_row_scan_covers_unknown_scrolled_phase (test_reply_safety.SafetyGateTest.test_pending_row_scan_covers_unknown_scrolled_phase) ... ok test_pending_search_deduplicates_same_row_on_overlapping_pages (test_reply_safety.SafetyGateTest.test_pending_search_deduplicates_same_row_on_overlapping_pages) ... ok test_pending_search_rejects_same_identity_on_different_pages (test_reply_safety.SafetyGateTest.test_pending_search_rejects_same_identity_on_different_pages) ... [待回复恢复] 跨分页发现多个相同视觉身份,已拒绝自动选择。 ok test_pending_search_resumes_after_budget_without_restarting_from_top (test_reply_safety.SafetyGateTest.test_pending_search_resumes_after_budget_without_restarting_from_top) Long lists must make forward progress across polling turns. ... [待回复恢复] 列表较长,本轮达到扫描上限;下轮从当前位置继续。 ok test_pending_search_scans_all_pages_then_replays_unique_page (test_reply_safety.SafetyGateTest.test_pending_search_scans_all_pages_then_replays_unique_page) ... ok test_pending_square_avatar_can_be_found_after_unread_badge_disappears (test_reply_safety.SafetyGateTest.test_pending_square_avatar_can_be_found_after_unread_badge_disappears) ... ok test_pending_task_freezes_original_chat_title_signature (test_reply_safety.SafetyGateTest.test_pending_task_freezes_original_chat_title_signature) ... ok test_persisted_name_hash_keeps_established_40_byte_key_layout (test_reply_safety.SafetyGateTest.test_persisted_name_hash_keeps_established_40_byte_key_layout) Do not silently reinterpret existing conversations.json keys. ... ok test_plain_surface_is_not_treated_as_modal (test_reply_safety.SafetyGateTest.test_plain_surface_is_not_treated_as_modal) ... ok test_post_paste_divider_check_ignores_sidebar_and_editor_text (test_reply_safety.SafetyGateTest.test_post_paste_divider_check_ignores_sidebar_and_editor_text) The final Enter gate must use the chat pane, not the whole window. ... ok test_previous_16_byte_archive_is_preferred_over_avatar_only_archive (test_reply_safety.SafetyGateTest.test_previous_16_byte_archive_is_preferred_over_avatar_only_archive) ... [档案] 已将旧版会话档案一次性迁移到新版复合会话键。 ok test_previous_16_byte_pending_is_atomically_rekeyed_after_title_proof (test_reply_safety.SafetyGateTest.test_previous_16_byte_pending_is_atomically_rekeyed_after_title_proof) ... [待回复恢复] 已将上一版待回复任务迁移到新版会话指纹。 ok test_proven_real_staff_name_confirms_reply_before_fast_followup (test_reply_safety.SafetyGateTest.test_proven_real_staff_name_confirms_reply_before_fast_followup) ... ok test_proven_render_alias_no_longer_swallows_the_first_new_message (test_reply_safety.SafetyGateTest.test_proven_render_alias_no_longer_swallows_the_first_new_message) 未读粗体与选中常规体已被证明是同一人,同样不能吞掉第一条消息。 ... [会话守护] 当前聊天页出现新内容,检查是否为客户未回复消息... [会话守护] 复制文字未证明有新客户消息,将用视觉确认是否新增媒体。 [会话守护] 发现客户新消息,先合并连续消息再回复。 ok test_qr_page_without_main_navigation_is_blocked (test_reply_safety.SafetyGateTest.test_qr_page_without_main_navigation_is_blocked) ... ok test_read_pending_conversation_is_reopened_by_fingerprint (test_reply_safety.SafetyGateTest.test_read_pending_conversation_is_reopened_by_fingerprint) ... [待回复恢复] 找到已读未回复会话,正在按头像和名称复合指纹重新打开。 [会话校验] 标题发生渲染变化,已通过头像和名称复合指纹确认仍是原会话。 ok test_real_wechat_external_avatar_survives_transient_nav_false (test_reply_safety.SafetyGateTest.test_real_wechat_external_avatar_survives_transient_nav_false) The green @微信 default avatar is a contact, not a system entry. ... [新消息] 正在处理 row0(坐标: 200, 148) [完成] 回复完成,红点已消失 → row0 ok test_receipt_and_fast_followup_are_committed_from_one_snapshot (test_reply_safety.SafetyGateTest.test_receipt_and_fast_followup_are_committed_from_one_snapshot) ... [待回复恢复] 已确认回复实际发出,完成档案提交且不会重复发送。 ok test_refresh_geometry_pane_unchanged_is_not_a_layout_change (test_reply_safety.SafetyGateTest.test_refresh_geometry_pane_unchanged_is_not_a_layout_change) ... ok test_refresh_geometry_shrinks_chat_region_when_sidebar_opens (test_reply_safety.SafetyGateTest.test_refresh_geometry_shrinks_chat_region_when_sidebar_opens) ... [几何刷新] 检测到右侧工具栏展开,聊天面板右边界收窄到 x=1550px。 [页面校准] 导航栏 320px→320px,会话列表 460px→460px,输入面板顶边 916px→916px;会话列表、消息区与输入区域已同步重算。 ok test_rejected_flat_row_render_drift_does_not_starve_next_unread (test_reply_safety.SafetyGateTest.test_rejected_flat_row_render_drift_does_not_starve_next_unread) A proven tool row stays excluded after font/selection render drift. ... ok test_render_probe_separates_dark_theme_from_an_empty_shell (test_reply_safety.SafetyGateTest.test_render_probe_separates_dark_theme_from_an_empty_shell) ... ok test_render_probe_survives_a_window_that_dies_mid_capture (test_reply_safety.SafetyGateTest.test_render_probe_survives_a_window_that_dies_mid_capture) ... ok test_repeated_resume_failures_back_off_instead_of_retrying_every_round (test_reply_safety.SafetyGateTest.test_repeated_resume_failures_back_off_instead_of_retrying_every_round) ... ok test_repeated_unknown_layout_escalates_to_maximize_then_multimodal_guard (test_reply_safety.SafetyGateTest.test_repeated_unknown_layout_escalates_to_maximize_then_multimodal_guard) ... [AI] 窗口布局已变化但内容尚未确认,保留原回复且不重复调用模型。 ok test_reply_without_generation_surface_still_records_pre_enter_baseline (test_reply_safety.SafetyGateTest.test_reply_without_generation_surface_still_records_pre_enter_baseline) AI-disabled/fixed-reply mode must not become permanently uncertain. ... ok test_reset_pending_batch_drops_the_cached_question_text (test_reply_safety.SafetyGateTest.test_reset_pending_batch_drops_the_cached_question_text) 放弃旧草稿必须连缓存的旧问题一起丢,下一轮才不会拿它再答一遍。 ... ok test_reset_pending_clears_uncertain_tracking_maps (test_reply_safety.SafetyGateTest.test_reset_pending_clears_uncertain_tracking_maps) ... ok test_restart_binds_bold_unread_pending_to_selected_regular_render (test_reply_safety.SafetyGateTest.test_restart_binds_bold_unread_pending_to_selected_regular_render) Persisted render metadata recovers one task without changing its key. ... [待回复恢复] 已从磁盘恢复 1 个未完成任务。 [待回复恢复] 已按持久化渲染身份找回红点消失前的会话任务。 [会话守护] 当前会话仍有已读未回复任务,正在安全重试... [会话守护] 复制文字未证明有新客户消息,将用视觉确认是否新增媒体。 [会话守护] 发现客户新消息,先合并连续消息再回复。 ok test_restart_only_retries_when_pre_send_surface_proves_enter_did_not_happen (test_reply_safety.SafetyGateTest.test_restart_only_retries_when_pre_send_surface_proves_enter_did_not_happen) ... [发送对账] 发送结果暂未确认,已保留当前任务并后台核对;不会重复发送,也不会阻塞其他会话。 ok test_restart_reconciles_visible_sent_reply_without_resending (test_reply_safety.SafetyGateTest.test_restart_reconciles_visible_sent_reply_without_resending) ... [待回复恢复] 已确认回复实际发出,完成档案提交且不会重复发送。 ok test_review_mode_keeps_verified_draft_and_never_presses_enter (test_reply_safety.SafetyGateTest.test_review_mode_keeps_verified_draft_and_never_presses_enter) ... [人工审核] 回复已填入输入框,等待人工审核发送。 ok test_right_side_unselectable_media_does_not_relabel_last_copied_customer (test_reply_safety.SafetyGateTest.test_right_side_unselectable_media_does_not_relabel_last_copied_customer) ... ok test_row_estimate_error_no_longer_forks_the_archive_key (test_reply_safety.SafetyGateTest.test_row_estimate_error_no_longer_forks_the_archive_key) 行锚点估算偏差绝不能让同一个联系人算出第二个档案键。 ... ok test_same_avatar_long_common_name_prefix_keeps_distinct_suffixes (test_reply_safety.SafetyGateTest.test_same_avatar_long_common_name_prefix_keeps_distinct_suffixes) ... ok test_same_avatar_names_differing_at_last_visible_character_stay_distinct (test_reply_safety.SafetyGateTest.test_same_avatar_names_differing_at_last_visible_character_stay_distinct) The final name glyph before the time column is part of session identity. ... ok test_same_avatar_short_names_with_different_first_character_stay_distinct (test_reply_safety.SafetyGateTest.test_same_avatar_short_names_with_different_first_character_stay_distinct) ... ok test_same_avatar_with_different_row_names_gets_distinct_session_keys (test_reply_safety.SafetyGateTest.test_same_avatar_with_different_row_names_gets_distinct_session_keys) ... ok test_same_avatar_with_different_title_never_resumes_cached_reply (test_reply_safety.SafetyGateTest.test_same_avatar_with_different_title_never_resumes_cached_reply) ... [待回复恢复] 找到已读未回复会话,正在按头像和名称复合指纹重新打开。 [待回复恢复] 头像相同但聊天标题不一致,已禁止回复。 ok test_same_chat_receipt_accepts_title_render_drift_with_full_selected_fp (test_reply_safety.SafetyGateTest.test_same_chat_receipt_accepts_title_render_drift_with_full_selected_fp) ... ok test_same_chat_receipt_uses_strong_chat_fallback_when_nav_colour_misses (test_reply_safety.SafetyGateTest.test_same_chat_receipt_uses_strong_chat_fallback_when_nav_colour_misses) ... ok test_same_contact_survives_the_measured_avatar_hash_drift (test_reply_safety.SafetyGateTest.test_same_contact_survives_the_measured_avatar_hash_drift) ... ok test_same_name_is_stable_between_normal_and_selected_row_colors (test_reply_safety.SafetyGateTest.test_same_name_is_stable_between_normal_and_selected_row_colors) ... ok test_same_title_never_overrides_a_different_full_selected_fingerprint (test_reply_safety.SafetyGateTest.test_same_title_never_overrides_a_different_full_selected_fingerprint) ... ok test_selected_blue_row_uses_background_inside_rounded_highlight (test_reply_safety.SafetyGateTest.test_selected_blue_row_uses_background_inside_rounded_highlight) 200% DPI selected rows must not compare avatar corners to outer white. ... ok test_selected_mail_is_not_mistaken_for_messages (test_reply_safety.SafetyGateTest.test_selected_mail_is_not_mistaken_for_messages) ... ok test_selected_mismatch_keeps_preclick_pending_on_disk (test_reply_safety.SafetyGateTest.test_selected_mismatch_keeps_preclick_pending_on_disk) A post-click render mismatch must not lose the now-read message. ... [新消息] 正在处理 row0(坐标: 200, 132) [页面校验] 目标会话本轮打不开,先服务其他未读会话,稍后再回来。 [新消息] 正在处理 row0(坐标: 200, 132) [页面校验] 目标会话本轮打不开,先服务其他未读会话,稍后再回来。 [新消息] 正在处理 row0(坐标: 200, 132) [页面校验] 目标会话本轮打不开,先服务其他未读会话,稍后再回来。 [新消息] 正在处理 row0(坐标: 200, 132) [页面校验] 目标会话本轮打不开,先服务其他未读会话,稍后再回来。 [新消息] 正在处理 row0(坐标: 200, 132) [页面校验] 目标会话本轮打不开,先服务其他未读会话,稍后再回来。 ok test_selected_pending_title_render_drift_still_reaches_reply_flow (test_reply_safety.SafetyGateTest.test_selected_pending_title_render_drift_still_reaches_reply_flow) ... [会话校验] 标题发生渲染变化,已通过头像和名称复合指纹确认仍是原会话。 [会话守护] 当前会话仍有已读未回复任务,正在安全重试... [会话守护] 复制文字未证明有新客户消息,将用视觉确认是否新增媒体。 ok test_selected_square_avatar_only_bypasses_tool_filter_for_exact_pending (test_reply_safety.SafetyGateTest.test_selected_square_avatar_only_bypasses_tool_filter_for_exact_pending) ... ok test_semantic_layout_hint_still_requires_local_pixel_boundaries (test_reply_safety.SafetyGateTest.test_semantic_layout_hint_still_requires_local_pixel_boundaries) ... [页面校准] 导航栏 136px→320px,会话列表 460px→500px,输入面板顶边 1000px→1000px;会话列表、消息区与输入区域已同步重算。 ok test_send_is_cancelled_before_click_when_chat_identity_changed (test_reply_safety.SafetyGateTest.test_send_is_cancelled_before_click_when_chat_identity_changed) ... [发送保护] 当前聊天对象已经变化,已取消粘贴和发送。 ok test_send_is_cancelled_when_input_geometry_is_invalid (test_reply_safety.SafetyGateTest.test_send_is_cancelled_when_input_geometry_is_invalid) ... [发送保护] 聊天输入区域空间不足,已禁止窗口外粘贴和发送。 ok test_send_is_cancelled_when_message_arrives_after_paste_before_enter (test_reply_safety.SafetyGateTest.test_send_is_cancelled_when_message_arrives_after_paste_before_enter) ... [发送保护] 按 Enter 前又收到新消息,已清除旧草稿并重新合并。 ok test_send_is_cancelled_when_new_message_arrives_after_generation (test_reply_safety.SafetyGateTest.test_send_is_cancelled_when_new_message_arrives_after_generation) ... [发送保护] 生成回复后又收到新消息,已取消旧回复并重新合并。 ok test_send_is_cancelled_when_pending_title_does_not_match (test_reply_safety.SafetyGateTest.test_send_is_cancelled_when_pending_title_does_not_match) ... [发送保护] 当前聊天对象已经变化,已取消粘贴和发送。 ok test_send_is_cancelled_when_selected_session_fingerprint_is_missing (test_reply_safety.SafetyGateTest.test_send_is_cancelled_when_selected_session_fingerprint_is_missing) ... [发送保护] 当前聊天对象已经变化,已取消粘贴和发送。 ok test_send_receipt_allows_bounded_delayed_render (test_reply_safety.SafetyGateTest.test_send_receipt_allows_bounded_delayed_render) ... ok test_send_receipt_deadline_stops_more_expensive_checks (test_reply_safety.SafetyGateTest.test_send_receipt_deadline_stops_more_expensive_checks) ... ok test_send_stops_immediately_after_internal_modal_handling (test_reply_safety.SafetyGateTest.test_send_stops_immediately_after_internal_modal_handling) ... [发送保护] 发送前处理了页面弹窗,本轮保留任务并重新校验。 ok test_send_stops_immediately_after_owned_blocker_handling (test_reply_safety.SafetyGateTest.test_send_stops_immediately_after_owned_blocker_handling) ... [发送保护] 发送前处理了阻塞子窗口,本轮保留任务并重新校验。 ok test_session_list_width_follows_the_persistent_visual_divider (test_reply_safety.SafetyGateTest.test_session_list_width_follows_the_persistent_visual_divider) ... ok test_session_vision_model_link_error_is_not_cached (test_reply_safety.SafetyGateTest.test_session_vision_model_link_error_is_not_cached) ... [AI会话分类] 未知未读行判断失败,保留后续页面复核:temporary link error [AI会话分类] 客户甲 → unknown / 0%(temporary link error) ok test_session_without_an_archive_baselines_when_the_agent_spoke_last (test_reply_safety.SafetyGateTest.test_session_without_an_archive_baselines_when_the_agent_spoke_last) 屏幕上最后一条是我方发的,说明没人在等回复,仍然只建基线。 ... [会话守护] 已建立当前聊天页基线;画面未变化时不会操作鼠标。 ok test_session_without_an_archive_recovers_its_first_unanswered_message (test_reply_safety.SafetyGateTest.test_session_without_an_archive_recovers_its_first_unanswered_message) 还没建档的会话,第一条没人回过的客户消息不能被基线吞掉。 ... [待回复恢复] 发现已读但没有回复的客户消息,正在恢复本次回复... [会话守护] 当前会话仍有已读未回复任务,正在安全重试... [会话守护] 复制文字未证明有新客户消息,将用视觉确认是否新增媒体。 [会话守护] 发现客户新消息,先合并连续消息再回复。 ok test_square_unread_avatar_is_kept_for_safe_visual_proof (test_reply_safety.SafetyGateTest.test_square_unread_avatar_is_kept_for_safe_visual_proof) A verified unread + full composite identity must not be discarded by shape. ... [会话识别] 检测到未读图标型头像候选,将先确认消息页与会话身份再回复。 ok test_startup_archive_delta_creates_pending_and_enters_retry (test_reply_safety.SafetyGateTest.test_startup_archive_delta_creates_pending_and_enters_retry) A selected read message newer than its archive snapshot is recoverable. ... [待回复恢复] 发现已读但没有回复的客户消息,正在恢复本次回复... [会话守护] 当前会话仍有已读未回复任务,正在安全重试... [会话守护] 复制文字未证明有新客户消息,将用视觉确认是否新增媒体。 [会话守护] 发现客户新消息,先合并连续消息再回复。 ok test_stubborn_internal_modal_freezes_poll_without_repeated_escape (test_reply_safety.SafetyGateTest.test_stubborn_internal_modal_freezes_poll_without_repeated_escape) ... [页面清理] 测试弹窗仍在,将限频重试且本轮不执行会话操作。 ok test_stubborn_owned_dialog_is_blocked_but_not_reclosed_every_poll (test_reply_safety.SafetyGateTest.test_stubborn_owned_dialog_is_blocked_but_not_reclosed_every_poll) ... [页面清理] 阻塞子窗口暂未关闭,将限频重试: 发送文档 ok test_stuck_pending_task_no_longer_starves_the_unread_scan (test_reply_safety.SafetyGateTest.test_stuck_pending_task_no_longer_starves_the_unread_scan) 端到端:卡住的任务存在时,本轮仍然必须去扫描新的未读会话。 ... ok test_successful_send_keeps_current_chat_open (test_reply_safety.SafetyGateTest.test_successful_send_keeps_current_chat_open) ... ok test_switching_sessions_starts_a_fresh_hold (test_reply_safety.SafetyGateTest.test_switching_sessions_starts_a_fresh_hold) 换到下一个会话时重新计时,不继承上一个会话烧掉的额度。 ... [排队] 当前会话已占用 61 秒仍未回完,先放行其他会话,稍后再回来处理它。 ok test_text_selection_region_is_clamped_inside_narrow_window (test_reply_safety.SafetyGateTest.test_text_selection_region_is_clamped_inside_narrow_window) ... [页面校准] 导航栏 136px→320px,会话列表 460px→460px,输入面板顶边 280px→280px;会话列表、消息区与输入区域已同步重算。 ok test_the_autosend_timer_starts_when_the_draft_first_appears (test_reply_safety.SafetyGateTest.test_the_autosend_timer_starts_when_the_draft_first_appears) 超时直发按"第一次看见这段字"计时,不能被每轮复查刷新。 ... ok test_the_drifted_avatar_canonicalizes_onto_the_existing_key (test_reply_safety.SafetyGateTest.test_the_drifted_avatar_canonicalizes_onto_the_existing_key) 归一化也必须认下这次漂移,否则同一个人当场被铸成第二把档案键。 ... ok test_the_filter_rechecks_itself_after_the_cooldown (test_reply_safety.SafetyGateTest.test_the_filter_rechecks_itself_after_the_cooldown) 企微改版或误判时必须能自己走回来。 ... ok test_the_gate_sends_the_existing_draft_once_the_timer_expires (test_reply_safety.SafetyGateTest.test_the_gate_sends_the_existing_draft_once_the_timer_expires) 端到端:时间到了,发出去的必须是**框里那句**,不是模型这轮生成的回复。 ... [发送保护] 输入框里这段字已放置 10.0 分钟,超过设置的 5 分钟,按设置直接发送框里的内容。 [发送兼容] 检测到 Enter 仅保留草稿,改用 Ctrl+Enter 发送。 [发送保护] 发送后暂未确认我方消息,已保留本会话并后台对账;不会重复发送,也不会阻塞其他会话。 ok test_the_hold_lets_the_session_back_in_after_the_window (test_reply_safety.SafetyGateTest.test_the_hold_lets_the_session_back_in_after_the_window) 不能永久拉黑:人把草稿删了之后,这个会话必须自己走得回来。 ... ok test_the_lone_bubble_at_the_top_is_found (test_reply_safety.SafetyGateTest.test_the_lone_bubble_at_the_top_is_found) ... ok test_the_message_workspace_overrides_any_qr_on_screen (test_reply_safety.SafetyGateTest.test_the_message_workspace_overrides_any_qr_on_screen) 消息工作区还在,就绝不可能是登录页。 ... ok test_the_open_session_is_served_before_anyone_else (test_reply_safety.SafetyGateTest.test_the_open_session_is_served_before_anyone_else) 正在回复的会话不能被别的会话抢走,否则这条回复要等下一轮重来。 ... ok test_the_raw_anchor_survives_a_restart (test_reply_safety.SafetyGateTest.test_the_raw_anchor_survives_a_restart) 重启后还要能核对回执,否则任务只能挂成待核对、客户白等。 ... [待回复恢复] 已从磁盘恢复 1 个未完成任务。 ok test_the_rest_of_the_queue_is_first_come_first_served (test_reply_safety.SafetyGateTest.test_the_rest_of_the_queue_is_first_come_first_served) 多个会话同时来消息就排队,按到达先后一条条处理。 ... ok test_the_scrollbar_gutter_never_counts_as_a_message (test_reply_safety.SafetyGateTest.test_the_scrollbar_gutter_never_counts_as_a_message) 右缘滚动条会随鼠标淡入淡出,算进墨迹就会把范围撑满整个面板。 ... ok test_the_send_gate_parks_the_session_when_it_meets_a_human_draft (test_reply_safety.SafetyGateTest.test_the_send_gate_parks_the_session_when_it_meets_a_human_draft) 端到端:真走一遍发送闸,确认既没发出去、也留下了跳过标记。 ... [发送保护] 检测到人工草稿,已保留原内容并取消自动发送。 ok test_the_skip_window_never_overshoots_a_shorter_autosend_setting (test_reply_safety.SafetyGateTest.test_the_skip_window_never_overshoots_a_shorter_autosend_setting) 设 2 分钟直发、复查窗口 5 分钟时,不能真等到 5 分钟才发。 ... ok test_the_staged_snapshot_reaches_the_archive (test_reply_safety.SafetyGateTest.test_the_staged_snapshot_reaches_the_archive) ... ok test_the_staged_snapshot_survives_a_restart (test_reply_safety.SafetyGateTest.test_the_staged_snapshot_survives_a_restart) 发送和入档之间进程挂掉,重启后这张画面不能丢。 ... [待回复恢复] 已从磁盘恢复 1 个未完成任务。 ok test_the_upward_search_gives_up_instead_of_scrolling_forever (test_reply_safety.SafetyGateTest.test_the_upward_search_gives_up_instead_of_scrolling_forever) 对方粘了一整份文档时不能一直翻下去,把这个会话拖死。 ... [剪贴板] 最新一条消息超过一屏,正在向上翻找开头… [剪贴板] 成功提取 96 行聊天记录(共采集 6 屏 / 去重后 96 行) ok test_tiny_chat_region_never_starts_mouse_drag (test_reply_safety.SafetyGateTest.test_tiny_chat_region_never_starts_mouse_drag) ... [剪贴板] 聊天框选区域空间不足,已禁止窗口外拖拽。 ok test_tiny_window_is_maximized_before_any_input_click (test_reply_safety.SafetyGateTest.test_tiny_window_is_maximized_before_any_input_click) ... [窗口托管] 企业微信窗口过小,正在最大化并重新进行视觉标定。 ok test_title_mismatch_without_selected_row_proof_remains_blocked (test_reply_safety.SafetyGateTest.test_title_mismatch_without_selected_row_proof_remains_blocked) ... ok test_title_render_rebind_failure_rolls_back_and_blocks (test_reply_safety.SafetyGateTest.test_title_render_rebind_failure_rolls_back_and_blocks) ... ok test_typing_status_below_title_does_not_change_chat_identity (test_reply_safety.SafetyGateTest.test_typing_status_below_title_does_not_change_chat_identity) ... ok test_ui_guard_conflicting_protocol_objects_fail_closed (test_reply_safety.SafetyGateTest.test_ui_guard_conflicting_protocol_objects_fail_closed) ... ok test_ui_guard_missing_protocol_field_fails_closed (test_reply_safety.SafetyGateTest.test_ui_guard_missing_protocol_field_fails_closed) ... ok test_ui_guard_rejects_model_action_that_does_not_match_state (test_reply_safety.SafetyGateTest.test_ui_guard_rejects_model_action_that_does_not_match_state) ... ok test_ui_guard_skips_unrelated_json_before_protocol_object (test_reply_safety.SafetyGateTest.test_ui_guard_skips_unrelated_json_before_protocol_object) ... ok test_uncertain_active_task_does_not_block_next_pending_session (test_reply_safety.SafetyGateTest.test_uncertain_active_task_does_not_block_next_pending_session) ... ok test_uncertain_receipt_is_rechecked_at_low_frequency (test_reply_safety.SafetyGateTest.test_uncertain_receipt_is_rechecked_at_low_frequency) ... [发送对账] 发送结果暂未确认,已保留当前任务并后台核对;不会重复发送,也不会阻塞其他会话。 ok test_uncertain_state_is_strictly_read_only_even_after_surface_change (test_reply_safety.SafetyGateTest.test_uncertain_state_is_strictly_read_only_even_after_surface_change) ... [时钟] 检测到系统时间被回拨(发现于发送对账)。已按“已过很久”重新裁定相关任务,避免超时判断永远不成立而卡死。 [发送对账] 发送结果暂未确认,已保留当前任务并后台核对;不会重复发送,也不会阻塞其他会话。 ok test_unchanged_selected_chat_does_not_activate_or_move_mouse (test_reply_safety.SafetyGateTest.test_unchanged_selected_chat_does_not_activate_or_move_mouse) ... ok test_unchanged_surface_after_escape_is_treated_as_false_positive (test_reply_safety.SafetyGateTest.test_unchanged_surface_after_escape_is_treated_as_false_positive) Esc 没有改变任何画面时,绝不能把聊天内容当弹窗冻结整轮轮询。 ... [页面清理] 测试Esc 前后该区域画面完全一致,判定为聊天内容误判,本轮继续正常回复。 ok test_unchanged_surface_reuses_staged_reply_without_model_call (test_reply_safety.SafetyGateTest.test_unchanged_surface_reuses_staged_reply_without_model_call) ... [AI] 聊天内容未变化,直接复用上次未发送成功的回复。 ok test_unconfirmed_navigation_width_mints_no_session_identity (test_reply_safety.SafetyGateTest.test_unconfirmed_navigation_width_mints_no_session_identity) 导航宽度未识别确认时绝不铸造会话键。 ... [会话身份] 导航栏宽度尚未识别确认,无法生成会话身份,自动回复已暂停 0 秒。请确认企业微信主界面已还原、且停在“消息”页。 ok test_unknown_followup_direction_keeps_a_pending_probe (test_reply_safety.SafetyGateTest.test_unknown_followup_direction_keeps_a_pending_probe) ... [消息续接] 回执画面中存在方向不明确的后续消息,已保留为下一轮待核对任务。 [待回复恢复] 已确认回复实际发出,完成档案提交且不会重复发送。 ok test_unknown_send_state_fails_closed_with_real_uncertain_timestamp (test_reply_safety.SafetyGateTest.test_unknown_send_state_fails_closed_with_real_uncertain_timestamp) ... [发送对账] 发送结果暂未确认,已保留当前任务并后台核对;不会重复发送,也不会阻塞其他会话。 ok test_unlocatable_pending_task_leaves_the_round_free_for_new_unread (test_reply_safety.SafetyGateTest.test_unlocatable_pending_task_leaves_the_round_free_for_new_unread) 扫描完整个列表也认不回来时,绝不能吃掉本轮的未读处理。 ... ok test_unread_badge_and_dynamic_time_do_not_change_session_identity (test_reply_safety.SafetyGateTest.test_unread_badge_and_dynamic_time_do_not_change_session_identity) ... ok test_unread_badge_disappearing_does_not_change_flat_contact_key (test_reply_safety.SafetyGateTest.test_unread_badge_disappearing_does_not_change_flat_contact_key) ... ok test_unread_bold_name_and_selected_regular_name_keep_same_identity (test_reply_safety.SafetyGateTest.test_unread_bold_name_and_selected_regular_name_keep_same_identity) WeCom removes unread bold weight when the row becomes selected. ... ok test_unread_group_band_requires_unique_exact_ocr_label (test_reply_safety.SafetyGateTest.test_unread_group_band_requires_unique_exact_ocr_label) ... [导航定位] “消息”入口不在默认位置,已按文字识别定位到 y 264~304px。 ok test_verified_square_avatar_stays_selectable_after_visual_proof_clears (test_reply_safety.SafetyGateTest.test_verified_square_avatar_stays_selectable_after_visual_proof_clears) ... ok test_visual_model_link_error_preserves_real_customer_task (test_reply_safety.SafetyGateTest.test_visual_model_link_error_preserves_real_customer_task) ... ok test_a_disabled_rule_never_matches (test_reply_safety.SelectiveReviewRuleTest.test_a_disabled_rule_never_matches) ... ok test_a_keyword_in_the_customer_text_triggers_review (test_reply_safety.SelectiveReviewRuleTest.test_a_keyword_in_the_customer_text_triggers_review) ... ok test_a_keyword_in_the_drafted_reply_also_triggers_review (test_reply_safety.SelectiveReviewRuleTest.test_a_keyword_in_the_drafted_reply_also_triggers_review) 客户问的和模型答的,沾上任意一边都算命中——模型自己说漏嘴同样要拦。 ... ok test_a_malformed_rules_list_fails_safe_by_finding_nothing (test_reply_safety.SelectiveReviewRuleTest.test_a_malformed_rules_list_fails_safe_by_finding_nothing) 本机读到的配置万一是坏的(同步中途、字段缺失),不能让轮询直接崩掉。 ... ok test_an_empty_rule_list_and_no_judge_never_triggers (test_reply_safety.SelectiveReviewRuleTest.test_an_empty_rule_list_and_no_judge_never_triggers) ... ok test_high_judge_risk_triggers_review_even_with_no_rules (test_reply_safety.SelectiveReviewRuleTest.test_high_judge_risk_triggers_review_even_with_no_rules) 非影子裁判判高风险时,一条关键词规则都没配也要拦。 ... ok test_judge_risk_check_is_case_insensitive_and_takes_priority (test_reply_safety.SelectiveReviewRuleTest.test_judge_risk_check_is_case_insensitive_and_takes_priority) ... ok test_matching_is_case_insensitive (test_reply_safety.SelectiveReviewRuleTest.test_matching_is_case_insensitive) ... ok test_medium_and_low_judge_risk_do_not_force_review_on_their_own (test_reply_safety.SelectiveReviewRuleTest.test_medium_and_low_judge_risk_do_not_force_review_on_their_own) ... ok test_ordinary_chat_does_not_trigger_review (test_reply_safety.SelectiveReviewRuleTest.test_ordinary_chat_does_not_trigger_review) ... ok test_a_message_without_a_snapshot_resolves_to_nothing (test_reply_safety.SessionViewerSnapshotTest.test_a_message_without_a_snapshot_resolves_to_nothing) ... ok test_a_missing_file_is_not_offered_to_the_viewer (test_reply_safety.SessionViewerSnapshotTest.test_a_missing_file_is_not_offered_to_the_viewer) ... ok test_a_path_in_the_archive_never_escapes_the_media_dir (test_reply_safety.SessionViewerSnapshotTest.test_a_path_in_the_archive_never_escapes_the_media_dir) 档案是磁盘上的文件,可能被改。只认纯文件名,不认任何路径。 ... ok test_a_stored_snapshot_resolves_under_the_media_dir (test_reply_safety.SessionViewerSnapshotTest.test_a_stored_snapshot_resolves_under_the_media_dir) ... ok test_a_blanket_mode_leftover_still_gets_cleared (test_reply_safety.StaleReviewFlagCleanupTest.test_a_blanket_mode_leftover_still_gets_cleared) 全局审核模式留下的标记(没有 review_reason)该清还是要清——这是这个函数本来的职责。 ... ok test_a_rule_triggered_hold_survives_the_cleanup (test_reply_safety.StaleReviewFlagCleanupTest.test_a_rule_triggered_hold_survives_the_cleanup) ... ok test_mixed_sessions_are_handled_independently (test_reply_safety.StaleReviewFlagCleanupTest.test_mixed_sessions_are_handled_independently) ... ok test_still_a_no_op_while_blanket_review_mode_is_on (test_reply_safety.StaleReviewFlagCleanupTest.test_still_a_no_op_while_blanket_review_mode_is_on) 全局开关还开着的时候,这个函数原本就该整个不动——这条防止我这次改动破坏了那条老行为。 ... ok test_exchange_id_is_committed_only_once_after_restart (test_reply_safety.TransactionStoreTest.test_exchange_id_is_committed_only_once_after_restart) ... ok test_registration_prepare_mode_does_not_write_before_send (test_reply_safety.TransactionStoreTest.test_registration_prepare_mode_does_not_write_before_send) ... ok test_visually_proven_outgoing_speaker_survives_restart (test_reply_safety.TransactionStoreTest.test_visually_proven_outgoing_speaker_survives_restart) ... ok test_completed_exchange_does_not_trigger_on_startup_or_repoll (test_self_reply_loop.ArchiveFeedbackTest.test_completed_exchange_does_not_trigger_on_startup_or_repoll) ... ok test_genuine_followup_after_reply_is_still_enqueued (test_self_reply_loop.ArchiveFeedbackTest.test_genuine_followup_after_reply_is_still_enqueued) ... [引擎B] 已登记新消息 → aa ok test_meta_records_after_reply_do_not_revive_old_customer_turn (test_self_reply_loop.ArchiveFeedbackTest.test_meta_records_after_reply_do_not_revive_old_customer_turn) ... ok test_new_customer_record_with_same_timestamp_as_answer_is_processed (test_self_reply_loop.ArchiveFeedbackTest.test_new_customer_record_with_same_timestamp_as_answer_is_processed) ... [引擎B] 已登记新消息 → aa ok test_packaged_archive_generation_and_send_flow (test_self_reply_loop.ArchiveFeedbackTest.test_packaged_archive_generation_and_send_flow) ... [引擎B] 已登记新消息 → aa [会话守护] 最后一条是我方发出的消息,没有需要回复的内容。 [会话守护] 最后一条是我方发出的消息,没有需要回复的内容。 ok test_saving_our_reply_does_not_create_another_customer_event (test_self_reply_loop.ArchiveFeedbackTest.test_saving_our_reply_does_not_create_another_customer_event) ... [引擎B] 已登记新消息 → aa ok test_known_staff_tail_is_not_answered_even_when_pixel_direction_is_unknown (test_self_reply_loop.OwnMessageGuardTest.test_known_staff_tail_is_not_answered_even_when_pixel_direction_is_unknown) ... [会话守护] 最后一条是我方发出的消息,没有需要回复的内容。 ok test_new_uncopyable_incoming_media_is_not_hidden_by_old_staff_text (test_self_reply_loop.OwnMessageGuardTest.test_new_uncopyable_incoming_media_is_not_hidden_by_old_staff_text) ... ok test_stale_unread_task_cannot_call_model_after_our_answer (test_self_reply_loop.OwnMessageGuardTest.test_stale_unread_task_cannot_call_model_after_our_answer) ... [会话守护] 最后一条是我方发出的消息,没有需要回复的内容。 ok test_unknown_staff_name_is_not_positive_customer_proof (test_self_reply_loop.OwnMessageGuardTest.test_unknown_staff_name_is_not_positive_customer_proof) ... [会话守护] 最后一条是我方发出的消息,没有需要回复的内容。 ok test_verified_customer_name_preserves_short_followup_despite_pixel_error (test_self_reply_loop.OwnMessageGuardTest.test_verified_customer_name_preserves_short_followup_despite_pixel_error) ... [会话守护] 底部气泡看似我方收尾,但文字确认最后一条是客户消息,继续回复。 ok test_failed_upload_is_outlet_failure_not_uncaught_gateway_exception (test_gateway_media_audit.DifyMediaAudit.test_failed_upload_is_outlet_failure_not_uncaught_gateway_exception) ... ERROR C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\unittest\case.py:622: RuntimeWarning: coroutine 'DifyMediaAudit.exercise..run' was never awaited with outcome.testPartExecutor(self): RuntimeWarning: Enable tracemalloc to get the object allocation traceback test_inline_image_uploaded_and_referenced_with_matching_user (test_gateway_media_audit.DifyMediaAudit.test_inline_image_uploaded_and_referenced_with_matching_user) ... ERROR test_jpeg_attachment_keeps_mime_type (test_gateway_media_audit.DifyMediaAudit.test_jpeg_attachment_keeps_mime_type) ... ERROR test_legacy_and_inline_same_image_uploads_once (test_gateway_media_audit.DifyMediaAudit.test_legacy_and_inline_same_image_uploads_once) ... ERROR test_remote_image_url_is_forwarded_as_attachment_not_downloaded (test_gateway_media_audit.DifyMediaAudit.test_remote_image_url_is_forwarded_as_attachment_not_downloaded) ... ERROR ====================================================================== ERROR: test_silk_real_decode_of_synthetic_pcm (test_voice_transcription.VoiceTranscriptionTests.test_silk_real_decode_of_synthetic_pcm) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_voice_transcription.py", line 212, in test_silk_real_decode_of_synthetic_pcm import pysilk ModuleNotFoundError: No module named 'pysilk' ====================================================================== ERROR: test_wav_transcribes_and_preserves_digest (test_voice_transcription.VoiceTranscriptionTests.test_wav_transcribes_and_preserves_digest) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_voice_transcription.py", line 64, in test_wav_transcribes_and_preserves_digest result = voice.transcribe_file(self.path, allowed_roots=[self.root], recognizer=lambda audio: "合成转写") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\wechat_rpa\voice_transcription.py", line 270, in transcribe_file return _recognize(raw, digest, recognizer or OfflineRecognizer(model_dir)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\wechat_rpa\voice_transcription.py", line 249, in _recognize audio = _decode_audio(raw) ^^^^^^^^^^^^^^^^^^ File "C:\wechat_rpa\voice_transcription.py", line 179, in _decode_audio raise VoiceTranscriptionError("dependency_missing") from None voice_transcription.VoiceTranscriptionError: 本地语音识别组件缺失,请修复安装 ====================================================================== ERROR: test_failed_upload_is_outlet_failure_not_uncaught_gateway_exception (test_gateway_media_audit.DifyMediaAudit.test_failed_upload_is_outlet_failure_not_uncaught_gateway_exception) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_gateway_media_audit.py", line 47, in test_failed_upload_is_outlet_failure_not_uncaught_gateway_exception result,outlet,requests=self.exercise(status=400,legacy=True) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\wechat_rpa\test_gateway_media_audit.py", line 29, in exercise result,outlet=asyncio.run(run()) ^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 189, in run with Runner(debug=debug) as runner: File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 59, in __enter__ self._lazy_init() File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 137, in _lazy_init self._loop = events.new_event_loop() ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\events.py", line 810, in new_event_loop return get_event_loop_policy().new_event_loop() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\events.py", line 699, in new_event_loop return self._loop_factory() ^^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\windows_events.py", line 315, in __init__ super().__init__(proactor) File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\proactor_events.py", line 639, in __init__ self._make_self_pipe() File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\proactor_events.py", line 784, in _make_self_pipe self._ssock, self._csock = socket.socketpair() ^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\socket.py", line 641, in socketpair csock.connect((addr, port)) File "C:\kefu\deploy\my-customers-20260918\run_isolated_customers.py", line 46, in loopback_connect return blocked("socket.connect")() ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\kefu\deploy\my-customers-20260918\run_isolated_customers.py", line 38, in reject raise RuntimeError("Audit blocks real external action: " + name) RuntimeError: Audit blocks real external action: socket.connect ====================================================================== ERROR: test_inline_image_uploaded_and_referenced_with_matching_user (test_gateway_media_audit.DifyMediaAudit.test_inline_image_uploaded_and_referenced_with_matching_user) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_gateway_media_audit.py", line 33, in test_inline_image_uploaded_and_referenced_with_matching_user result,_,requests=self.exercise() ^^^^^^^^^^^^^^^ File "C:\wechat_rpa\test_gateway_media_audit.py", line 29, in exercise result,outlet=asyncio.run(run()) ^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 189, in run with Runner(debug=debug) as runner: File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 59, in __enter__ self._lazy_init() File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 137, in _lazy_init self._loop = events.new_event_loop() ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\events.py", line 810, in new_event_loop return get_event_loop_policy().new_event_loop() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\events.py", line 699, in new_event_loop return self._loop_factory() ^^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\windows_events.py", line 315, in __init__ super().__init__(proactor) File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\proactor_events.py", line 639, in __init__ self._make_self_pipe() File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\proactor_events.py", line 784, in _make_self_pipe self._ssock, self._csock = socket.socketpair() ^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\socket.py", line 641, in socketpair csock.connect((addr, port)) File "C:\kefu\deploy\my-customers-20260918\run_isolated_customers.py", line 46, in loopback_connect return blocked("socket.connect")() ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\kefu\deploy\my-customers-20260918\run_isolated_customers.py", line 38, in reject raise RuntimeError("Audit blocks real external action: " + name) RuntimeError: Audit blocks real external action: socket.connect ====================================================================== ERROR: test_jpeg_attachment_keeps_mime_type (test_gateway_media_audit.DifyMediaAudit.test_jpeg_attachment_keeps_mime_type) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_gateway_media_audit.py", line 59, in test_jpeg_attachment_keeps_mime_type _,_,requests=self.exercise(extra={'type':'image_url','image_url':{'url':'data:image/jpeg;base64,'+PNG}}) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\wechat_rpa\test_gateway_media_audit.py", line 29, in exercise result,outlet=asyncio.run(run()) ^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 189, in run with Runner(debug=debug) as runner: File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 59, in __enter__ self._lazy_init() File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 137, in _lazy_init self._loop = events.new_event_loop() ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\events.py", line 810, in new_event_loop return get_event_loop_policy().new_event_loop() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\events.py", line 699, in new_event_loop return self._loop_factory() ^^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\windows_events.py", line 315, in __init__ super().__init__(proactor) File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\proactor_events.py", line 639, in __init__ self._make_self_pipe() File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\proactor_events.py", line 784, in _make_self_pipe self._ssock, self._csock = socket.socketpair() ^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\socket.py", line 641, in socketpair csock.connect((addr, port)) File "C:\kefu\deploy\my-customers-20260918\run_isolated_customers.py", line 46, in loopback_connect return blocked("socket.connect")() ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\kefu\deploy\my-customers-20260918\run_isolated_customers.py", line 38, in reject raise RuntimeError("Audit blocks real external action: " + name) RuntimeError: Audit blocks real external action: socket.connect ====================================================================== ERROR: test_legacy_and_inline_same_image_uploads_once (test_gateway_media_audit.DifyMediaAudit.test_legacy_and_inline_same_image_uploads_once) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_gateway_media_audit.py", line 43, in test_legacy_and_inline_same_image_uploads_once _,_,requests=self.exercise(legacy=True) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\wechat_rpa\test_gateway_media_audit.py", line 29, in exercise result,outlet=asyncio.run(run()) ^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 189, in run with Runner(debug=debug) as runner: File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 59, in __enter__ self._lazy_init() File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 137, in _lazy_init self._loop = events.new_event_loop() ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\events.py", line 810, in new_event_loop return get_event_loop_policy().new_event_loop() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\events.py", line 699, in new_event_loop return self._loop_factory() ^^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\windows_events.py", line 315, in __init__ super().__init__(proactor) File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\proactor_events.py", line 639, in __init__ self._make_self_pipe() File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\proactor_events.py", line 784, in _make_self_pipe self._ssock, self._csock = socket.socketpair() ^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\socket.py", line 641, in socketpair csock.connect((addr, port)) File "C:\kefu\deploy\my-customers-20260918\run_isolated_customers.py", line 46, in loopback_connect return blocked("socket.connect")() ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\kefu\deploy\my-customers-20260918\run_isolated_customers.py", line 38, in reject raise RuntimeError("Audit blocks real external action: " + name) RuntimeError: Audit blocks real external action: socket.connect ====================================================================== ERROR: test_remote_image_url_is_forwarded_as_attachment_not_downloaded (test_gateway_media_audit.DifyMediaAudit.test_remote_image_url_is_forwarded_as_attachment_not_downloaded) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_gateway_media_audit.py", line 54, in test_remote_image_url_is_forwarded_as_attachment_not_downloaded _,_,requests=self.exercise(extra={'type':'image_url','image_url':{'url':'https://images.example/test.jpg'}}) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\wechat_rpa\test_gateway_media_audit.py", line 29, in exercise result,outlet=asyncio.run(run()) ^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 189, in run with Runner(debug=debug) as runner: File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 59, in __enter__ self._lazy_init() File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 137, in _lazy_init self._loop = events.new_event_loop() ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\events.py", line 810, in new_event_loop return get_event_loop_policy().new_event_loop() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\events.py", line 699, in new_event_loop return self._loop_factory() ^^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\windows_events.py", line 315, in __init__ super().__init__(proactor) File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\proactor_events.py", line 639, in __init__ self._make_self_pipe() File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\asyncio\proactor_events.py", line 784, in _make_self_pipe self._ssock, self._csock = socket.socketpair() ^^^^^^^^^^^^^^^^^^^ File "C:\Users\isard\AppData\Local\Programs\Python\Python311\Lib\socket.py", line 641, in socketpair csock.connect((addr, port)) File "C:\kefu\deploy\my-customers-20260918\run_isolated_customers.py", line 46, in loopback_connect return blocked("socket.connect")() ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\kefu\deploy\my-customers-20260918\run_isolated_customers.py", line 38, in reject raise RuntimeError("Audit blocks real external action: " + name) RuntimeError: Audit blocks real external action: socket.connect ====================================================================== FAIL: test_accounts_conversations_and_message_ids_do_not_share_results (test_voice_transcription.VoiceTranscriptionTests.test_accounts_conversations_and_message_ids_do_not_share_results) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_voice_transcription.py", line 114, in test_accounts_conversations_and_message_ids_do_not_share_results self.assertEqual(texts, ["第一段", "第二段", "第三段", "第四段"]) AssertionError: Lists differ: ['', '', '', ''] != ['第一段', '第二段', '第三段', '第四段'] First differing element 0: '' '第一段' - ['', '', '', ''] + ['第一段', '第二段', '第三段', '第四段'] ====================================================================== FAIL: test_change_during_recognition_drops_old_result (test_voice_transcription.VoiceTranscriptionTests.test_change_during_recognition_drops_old_result) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_voice_transcription.py", line 141, in test_change_during_recognition_drops_old_result self.assertTrue(entered.wait(2)) AssertionError: False is not true ====================================================================== FAIL: test_close_discards_text_and_stops_new_jobs (test_voice_transcription.VoiceTranscriptionTests.test_close_discards_text_and_stops_new_jobs) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_voice_transcription.py", line 180, in test_close_discards_text_and_stops_new_jobs self.assertEqual(self.wait(service)["status"], "ready") AssertionError: 'error' != 'ready' - error + ready ====================================================================== FAIL: test_duration_limit_rejects_instead_of_truncating (test_voice_transcription.VoiceTranscriptionTests.test_duration_limit_rejects_instead_of_truncating) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_voice_transcription.py", line 209, in test_duration_limit_rejects_instead_of_truncating self.assertEqual(error.exception.code, "audio_too_long") AssertionError: 'dependency_missing' != 'audio_too_long' - dependency_missing + audio_too_long ====================================================================== FAIL: test_empty_recognition_never_becomes_ready (test_voice_transcription.VoiceTranscriptionTests.test_empty_recognition_never_becomes_ready) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_voice_transcription.py", line 163, in test_empty_recognition_never_becomes_ready self.assertEqual(result["error_code"], "audio_empty") AssertionError: 'dependency_missing' != 'audio_empty' - dependency_missing + audio_empty ====================================================================== FAIL: test_failures_back_off_and_do_not_leak_exception_details (test_voice_transcription.VoiceTranscriptionTests.test_failures_back_off_and_do_not_leak_exception_details) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_voice_transcription.py", line 155, in test_failures_back_off_and_do_not_leak_exception_details self.assertEqual(result["error_code"], "recognition_failed") AssertionError: 'dependency_missing' != 'recognition_failed' - dependency_missing + recognition_failed ====================================================================== FAIL: test_missing_model_fails_without_network (test_voice_transcription.VoiceTranscriptionTests.test_missing_model_fails_without_network) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_voice_transcription.py", line 226, in test_missing_model_fails_without_network self.assertEqual(error.exception.code, "model_missing") AssertionError: 'dependency_missing' != 'model_missing' - dependency_missing + model_missing ====================================================================== FAIL: test_queue_is_bounded (test_voice_transcription.VoiceTranscriptionTests.test_queue_is_bounded) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_voice_transcription.py", line 174, in test_queue_is_bounded self.assertTrue(entered.wait(2)) AssertionError: False is not true ====================================================================== FAIL: test_request_is_fast_while_worker_waits (test_voice_transcription.VoiceTranscriptionTests.test_request_is_fast_while_worker_waits) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_voice_transcription.py", line 103, in test_request_is_fast_while_worker_waits self.assertTrue(entered.wait(2)) AssertionError: False is not true ====================================================================== FAIL: test_same_message_changed_audio_is_not_cached (test_voice_transcription.VoiceTranscriptionTests.test_same_message_changed_audio_is_not_cached) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_voice_transcription.py", line 130, in test_same_message_changed_audio_is_not_cached self.assertEqual(second["text"], "新语音") AssertionError: '' != '新语音' + 新语音 ====================================================================== FAIL: test_same_message_same_audio_is_recognized_once (test_voice_transcription.VoiceTranscriptionTests.test_same_message_same_audio_is_recognized_once) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_voice_transcription.py", line 120, in test_same_message_same_audio_is_recognized_once self.assertEqual(self.wait(service)["status"], "ready") AssertionError: 'error' != 'ready' - error + ready ====================================================================== FAIL: test_silence_is_not_sent_to_model (test_voice_transcription.VoiceTranscriptionTests.test_silence_is_not_sent_to_model) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_voice_transcription.py", line 197, in test_silence_is_not_sent_to_model self.assertEqual(result["error_code"], "audio_empty") AssertionError: 'dependency_missing' != 'audio_empty' - dependency_missing + audio_empty ====================================================================== FAIL: test_pure_voice_never_asks_a_model_to_guess_audio (test_reply_safety.MediaReplyTest.test_pure_voice_never_asks_a_model_to_guess_audio) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\wechat_rpa\test_reply_safety.py", line 617, in test_pure_voice_never_asks_a_model_to_guess_audio self.assertEqual(bot._generate_ai_reply(fp), expected) AssertionError: None != '这条语音我这边暂时没法准确听清,麻烦您把重点打成文字发我一下。' ---------------------------------------------------------------------- Ran 651 tests in 48.685s FAILED (failures=13, errors=7)