mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
fix(realtime): keep a Muse turn active for turnless partials after speechEnd
Muse partials carry no turnId and belong to the most recent speechStart, and the docs say the model may keep post processing a turn after speechEnd until speechComplete. Releasing the active turn on speechEnd made any partial arriving in that window raise and get dropped in ENDPOINTING mode. The turn now stays active until its speechComplete or final transcript.
This commit is contained in:
parent
a2e383a1a5
commit
4647cd1215
2 changed files with 19 additions and 1 deletions
|
|
@ -517,7 +517,6 @@ class MuseEventTransformer:
|
|||
def _speech_end(self, message: Mapping[str, JsonValue]) -> _TurnState:
|
||||
turn: Final = self._turn(_required_turn_id(message, "speechEnd"))
|
||||
turn.stopped = True
|
||||
self._release_active(turn)
|
||||
return turn
|
||||
|
||||
def _speech_complete(self, message: Mapping[str, JsonValue]) -> _TurnState:
|
||||
|
|
|
|||
|
|
@ -241,6 +241,25 @@ def test_speech_end_then_speech_complete_emits_stopped_then_completed():
|
|||
assert completed[0]["transcript"] == "done"
|
||||
|
||||
|
||||
def test_turnless_partial_between_speech_end_and_speech_complete_stays_on_that_turn():
|
||||
transformer = MuseEventTransformer()
|
||||
transformer.transform(json.loads(_event("speechStart", turnId="turn-1")))
|
||||
transformer.transform(json.loads(_event("transcript", transcript="what is", final=False)))
|
||||
transformer.transform(json.loads(_event("speechEnd", turnId="turn-1")))
|
||||
|
||||
post_processed = transformer.transform(
|
||||
json.loads(_event("transcript", transcript="what is the weather", final=False))
|
||||
)
|
||||
completed = transformer.transform(
|
||||
json.loads(_event("speechComplete", turnId="turn-1", transcript="What is the weather?"))
|
||||
)
|
||||
|
||||
assert _typed(post_processed) == [("conversation.item.input_audio_transcription.delta", "turn-1")]
|
||||
assert post_processed[0]["delta"] == " the weather"
|
||||
assert _typed(completed) == [("conversation.item.input_audio_transcription.completed", "turn-1")]
|
||||
assert completed[0]["transcript"] == "What is the weather?"
|
||||
|
||||
|
||||
def _typed(events: tuple[dict[str, object], ...]) -> list[tuple[object, object]]:
|
||||
return [(event["type"], event["item_id"]) for event in events]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue