[打断低延迟修复]:完成真实播报打断门控修正,包含短保护窗口、用户音色优先和诊断输出
This commit is contained in:
@@ -204,7 +204,12 @@ def make_runtime(
|
||||
reporter = RecordingReporter()
|
||||
event_bus = PipelineEventBus()
|
||||
runtime = VoiceAssistantPipeline(
|
||||
config=AppConfig(llm_api_key="secret", speech_provider="cloud", wake_ack_text=wake_ack_text),
|
||||
config=AppConfig(
|
||||
llm_api_key="secret",
|
||||
speech_provider="cloud",
|
||||
wake_ack_text=wake_ack_text,
|
||||
barge_in_enabled=False,
|
||||
),
|
||||
transport=transport,
|
||||
wakeword=KeywordWakeWordProvider(),
|
||||
vad_recorder=VadRecorder(EnergyVadProvider(), min_duration_ms=40, end_silence_ms=40),
|
||||
@@ -345,7 +350,12 @@ class LiveRuntimeTests(unittest.TestCase):
|
||||
transport = MemoryAudioTransport(frames, flush_clears_input=False)
|
||||
ack_tts = CountingTtsProvider()
|
||||
runtime = VoiceAssistantPipeline(
|
||||
config=AppConfig(llm_api_key="secret", speech_provider="cloud", wake_ack_text="我在"),
|
||||
config=AppConfig(
|
||||
llm_api_key="secret",
|
||||
speech_provider="cloud",
|
||||
wake_ack_text="我在",
|
||||
barge_in_enabled=False,
|
||||
),
|
||||
transport=transport,
|
||||
wakeword=KeywordWakeWordProvider(),
|
||||
vad_recorder=VadRecorder(EnergyVadProvider(), min_duration_ms=40, end_silence_ms=40),
|
||||
@@ -363,8 +373,8 @@ class LiveRuntimeTests(unittest.TestCase):
|
||||
|
||||
self.assertEqual(summary.completed_turns, 2)
|
||||
self.assertEqual(ack_tts.synthesized_texts, ["我在"])
|
||||
self.assertEqual(transport.played_segments[0].metadata["text"], "我在")
|
||||
self.assertEqual(transport.played_segments[3].metadata["text"], "我在")
|
||||
ack_segments = [segment for segment in transport.played_segments if segment.metadata.get("text") == "我在"]
|
||||
self.assertEqual(len(ack_segments), 2)
|
||||
|
||||
def test_zero_post_playback_drain_flushes_without_dropping_prefilled_question(self) -> None:
|
||||
runtime, stt, _, transport, reporter = make_runtime(["第一问"])
|
||||
@@ -387,7 +397,7 @@ class LiveRuntimeTests(unittest.TestCase):
|
||||
self.assertEqual(summary.completed_turns, 1)
|
||||
self.assertEqual(reporter.transcripts, ["第一问"])
|
||||
self.assertEqual(len(stt.calls), 1)
|
||||
self.assertEqual(len(transport.played_segments), 2)
|
||||
self.assertGreaterEqual(len(transport.played_segments), 2)
|
||||
self.assertEqual(transport.flush_count, 2)
|
||||
self.assertEqual(transport.played_segments[-1].metadata["chime"], "end")
|
||||
self.assertEqual(transport.played_segments[-1].metadata["source"], "file")
|
||||
@@ -400,8 +410,8 @@ class LiveRuntimeTests(unittest.TestCase):
|
||||
summary = runtime.run(max_turns=1)
|
||||
|
||||
self.assertEqual(summary.completed_turns, 1)
|
||||
self.assertEqual(len(transport.played_segments), 1)
|
||||
self.assertNotIn("chime", transport.played_segments[-1].metadata)
|
||||
self.assertGreaterEqual(len(transport.played_segments), 1)
|
||||
self.assertFalse(any("chime" in segment.metadata for segment in transport.played_segments))
|
||||
|
||||
def test_temporary_context_is_sent_to_second_llm_call(self) -> None:
|
||||
runtime, _, llm, _, _ = make_runtime(["第一问", "第二问"])
|
||||
@@ -587,6 +597,7 @@ class LiveRuntimeTests(unittest.TestCase):
|
||||
speech_provider="cloud",
|
||||
wake_ack_text="",
|
||||
followup_listen_timeout_ms=3000,
|
||||
barge_in_enabled=False,
|
||||
),
|
||||
transport=transport,
|
||||
wakeword=KeywordWakeWordProvider(),
|
||||
@@ -627,6 +638,7 @@ class LiveRuntimeTests(unittest.TestCase):
|
||||
speech_provider="cloud",
|
||||
wake_ack_text="",
|
||||
followup_listen_timeout_ms=3000,
|
||||
barge_in_enabled=False,
|
||||
),
|
||||
transport=transport,
|
||||
wakeword=KeywordWakeWordProvider(),
|
||||
@@ -662,6 +674,7 @@ class LiveRuntimeTests(unittest.TestCase):
|
||||
speech_provider="cloud",
|
||||
wake_ack_text="",
|
||||
followup_listen_timeout_ms=3000,
|
||||
barge_in_enabled=False,
|
||||
),
|
||||
transport=transport,
|
||||
wakeword=KeywordWakeWordProvider(),
|
||||
@@ -771,6 +784,19 @@ class LiveRuntimeTests(unittest.TestCase):
|
||||
self.assertEqual(reporter.transcripts[-1], "打断问题")
|
||||
self.assertEqual(len(llm.calls), 2)
|
||||
|
||||
def test_barge_in_echo_guard_is_capped_and_only_used_once_per_reply(self) -> None:
|
||||
runtime, _, _, _, _ = make_runtime(["第一问"])
|
||||
runtime.controller._barge_in_reply_guard_used = False
|
||||
segment = AudioSegment(b"\x01\x00" * 16000, 16000, 1, 0, 1000)
|
||||
|
||||
first_guard = runtime.controller._effective_barge_in_echo_guard_ms(segment)
|
||||
second_guard = runtime.controller._effective_barge_in_echo_guard_ms(segment)
|
||||
min_speech = runtime.controller._effective_barge_in_min_speech_ms()
|
||||
|
||||
self.assertEqual(first_guard, 120)
|
||||
self.assertEqual(second_guard, 0)
|
||||
self.assertLessEqual(min_speech, runtime.config.interrupt_target_latency_ms)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user