[持续对话判定]:完成恢复待机延迟修复,包含本地规则收敛和分类器跳过回归测试

This commit is contained in:
mkbk
2026-06-18 13:51:35 +08:00
parent 86a429f018
commit ac72738fc8
3 changed files with 71 additions and 15 deletions
+18
View File
@@ -58,6 +58,24 @@ class ContinuationDecisionTests(unittest.TestCase):
self.assertEqual(decision.action, "standby")
self.assertEqual(len(llm.calls), 1)
def test_hybrid_generic_completed_reply_does_not_call_llm_classifier(self) -> None:
llm = FakeClassifierLlm('{"action":"continue","confidence":0.99,"reason":"不应调用"}')
provider = HybridContinuationDecisionProvider(
RuleContinuationDecisionProvider(),
LlmContinuationDecisionProvider(llm, threshold=0.65),
threshold=0.65,
)
decision = provider.decide(
user_text="没有呢",
assistant_text="明白了,我先保持待机。有需要再叫我就行。",
history=[],
)
self.assertEqual(decision.action, "standby")
self.assertEqual(decision.provider, "rule")
self.assertEqual(llm.calls, [])
def test_hybrid_high_confidence_llm_can_continue(self) -> None:
llm = FakeClassifierLlm('{"action":"continue","confidence":0.91,"reason":"等待用户选择"}')
provider = HybridContinuationDecisionProvider(
+32
View File
@@ -594,6 +594,38 @@ class LiveRuntimeTests(unittest.TestCase):
self.assertEqual(event_types[-1], STANDBY_RESUMED)
self.assertEqual(len(llm.calls), 1)
def test_completed_reply_returns_to_standby_without_cloud_classifier_delay(self) -> None:
frames = [wake_frame(0, 0)]
frames.extend(segment_frames(1, 20, partials=["没有呢", "没有呢"]))
transport = MemoryAudioTransport(frames, flush_clears_input=False)
llm = QueueLlmProvider([["明白了,我先保持待机。有需要再叫我就行。"]])
runtime = VoiceAssistantPipeline(
config=AppConfig(
llm_api_key="secret",
speech_provider="cloud",
wake_ack_text="",
followup_listen_timeout_ms=3000,
),
transport=transport,
wakeword=KeywordWakeWordProvider(),
vad_recorder=VadRecorder(EnergyVadProvider(), min_duration_ms=40, end_silence_ms=40),
stt=QueueSttProvider(["没有呢"]),
realtime_stt=MetadataSttProvider(),
llm=llm,
tts=SineTtsProvider(),
context=ConversationContext(),
reporter=RecordingReporter(),
event_bus=PipelineEventBus(),
)
summary = runtime.run(max_turns=1)
event_types = [event.type for event in runtime.event_bus.events]
self.assertEqual(summary.completed_turns, 1)
self.assertNotIn(FOLLOWUP_LISTENING, event_types)
self.assertEqual(event_types[-1], STANDBY_RESUMED)
self.assertEqual(len(llm.calls), 1)
def test_barge_in_interrupts_playback_and_keeps_only_spoken_context(self) -> None:
first_question_frames = [wake_frame(0, 0)]
first_question_frames.extend(segment_frames(1, 20, partials=["第一问", "第一问"]))