Compare commits

...

2 Commits

Author SHA1 Message Date
Xin Wang
26458faa6c Fix Unbounded _audio_buffer growth. 2026-02-06 08:11:14 +08:00
Xin Wang
605968a639 Fix _stop_current_speech doesn’t cancel LLM/TTS services. 2026-02-06 08:05:33 +08:00

View File

@@ -108,6 +108,8 @@ class DuplexPipeline:
self._is_bot_speaking = False
self._current_turn_task: Optional[asyncio.Task] = None
self._audio_buffer: bytes = b""
max_buffer_seconds = settings.max_audio_buffer_seconds if hasattr(settings, "max_audio_buffer_seconds") else 30
self._max_audio_buffer_bytes = int(settings.sample_rate * 2 * max_buffer_seconds)
self._last_vad_status: str = "Silence"
# Interruption handling
@@ -263,6 +265,9 @@ class DuplexPipeline:
# 3. Buffer audio for ASR
if vad_status == "Speech" or self.conversation.state == ConversationState.LISTENING:
self._audio_buffer += pcm_bytes
if len(self._audio_buffer) > self._max_audio_buffer_bytes:
# Keep only the most recent audio to cap memory usage
self._audio_buffer = self._audio_buffer[-self._max_audio_buffer_bytes:]
await self.asr_service.send_audio(pcm_bytes)
# For SiliconFlow ASR, trigger interim transcription periodically
@@ -669,6 +674,12 @@ class DuplexPipeline:
await self._current_turn_task
except asyncio.CancelledError:
pass
# Ensure underlying services are cancelled to avoid leaking work/audio
if self.tts_service:
await self.tts_service.cancel()
if self.llm_service and hasattr(self.llm_service, 'cancel'):
self.llm_service.cancel()
self._is_bot_speaking = False
self._interrupt_event.clear()