Implement response handling and speech tracking in CallEnd functionality
- Add begin_response and finish_after_current_speech methods to CallEndCoordinator for better management of speech events. - Update PromptBrain to utilize new methods, ensuring proper handling of generated closing speech and tool-only calls. - Enhance tests to verify the correct behavior of speech tracking and response handling in various scenarios, including waiting for audio to finish before ending calls. - Introduce a new test suite for CallEndCoordinator to validate the interaction with speech frames.
This commit is contained in:
@@ -17,6 +17,7 @@ class CallEndCoordinator:
|
||||
self._ending = False
|
||||
self._armed = False
|
||||
self._speaking = False
|
||||
self._response_speech_started = False
|
||||
self._finished = False
|
||||
self._reason = "completed"
|
||||
|
||||
@@ -28,7 +29,22 @@ class CallEndCoordinator:
|
||||
self._ending = True
|
||||
self._reason = reason or "completed"
|
||||
|
||||
def begin_response(self) -> None:
|
||||
"""Start tracking speech produced by one LLM response."""
|
||||
self._response_speech_started = False
|
||||
|
||||
def arm_after_speech(self) -> None:
|
||||
"""Wait for the next observed bot speech to finish."""
|
||||
self._armed = True
|
||||
|
||||
async def finish_after_current_speech(self, *, has_text: bool) -> None:
|
||||
"""Finish now if speech is absent/done, otherwise wait for its stop."""
|
||||
if not has_text:
|
||||
await self.finish()
|
||||
return
|
||||
if self._response_speech_started and not self._speaking:
|
||||
await self.finish()
|
||||
return
|
||||
self._armed = True
|
||||
|
||||
async def finish(self) -> None:
|
||||
@@ -38,15 +54,14 @@ class CallEndCoordinator:
|
||||
await self._queue_end(self._reason)
|
||||
|
||||
async def observe(self, frame) -> None:
|
||||
if isinstance(frame, BotStartedSpeakingFrame) and self._armed:
|
||||
if isinstance(frame, BotStartedSpeakingFrame):
|
||||
self._speaking = True
|
||||
elif (
|
||||
isinstance(frame, BotStoppedSpeakingFrame)
|
||||
and self._armed
|
||||
and self._speaking
|
||||
):
|
||||
logger.info("结束语播报完毕,挂断通话")
|
||||
await self.finish()
|
||||
self._response_speech_started = True
|
||||
elif isinstance(frame, BotStoppedSpeakingFrame) and self._speaking:
|
||||
self._speaking = False
|
||||
if self._armed:
|
||||
logger.info("结束语播报完毕,挂断通话")
|
||||
await self.finish()
|
||||
|
||||
|
||||
class EndCallAfterSpeechProcessor(FrameProcessor):
|
||||
|
||||
Reference in New Issue
Block a user