diff --git a/engine/core/conversation.py b/engine/core/conversation.py index f3cb63a..a3712e6 100644 --- a/engine/core/conversation.py +++ b/engine/core/conversation.py @@ -205,7 +205,10 @@ class ConversationManager: self._current_assistant_text = "" if was_interrupted: - await self.set_state(ConversationState.INTERRUPTED) + # A new user turn may already be active (LISTENING) when interrupted. + # Avoid overriding it back to INTERRUPTED, which can stall EOU flow. + if self.state != ConversationState.LISTENING: + await self.set_state(ConversationState.INTERRUPTED) else: await self.set_state(ConversationState.IDLE) diff --git a/engine/core/duplex_pipeline.py b/engine/core/duplex_pipeline.py index 074189a..aece39f 100644 --- a/engine/core/duplex_pipeline.py +++ b/engine/core/duplex_pipeline.py @@ -420,7 +420,7 @@ class DuplexPipeline: async def _on_speech_start(self) -> None: """Handle user starting to speak.""" - if self.conversation.state == ConversationState.IDLE: + if self.conversation.state in (ConversationState.IDLE, ConversationState.INTERRUPTED): await self.conversation.start_user_turn() self._audio_buffer = b"" self._last_sent_transcript = "" @@ -436,7 +436,7 @@ class DuplexPipeline: async def _on_end_of_utterance(self) -> None: """Handle end of user utterance.""" - if self.conversation.state != ConversationState.LISTENING: + if self.conversation.state not in (ConversationState.LISTENING, ConversationState.INTERRUPTED): return # Stop interim transcriptions