[持续对话判定]:完成恢复待机延迟修复,包含本地规则收敛和分类器跳过回归测试
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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=["第一问", "第一问"]))
|
||||
|
||||
Reference in New Issue
Block a user