fix(openai realtime): treat create_response=False as client-side turn taking - #6642
fix(openai realtime): treat create_response=False as client-side turn taking#6642longcw wants to merge 2 commits into
Conversation
… taking Server VAD with create_response=False keeps committing and transcribing the user audio, but the reply is the client's call, so the model is not doing turn taking for the session. Reporting turn_detection=True there rejected allow_interruptions=False and cancelled the ongoing response on every detected user turn. Also carries interrupt_response through the deprecated session.TurnDetection conversion for server_vad, and ignores input_audio_buffer_commit_empty while the server VAD owns the buffer. Fixes #6635
interrupt_response is a separate switch: left enabled the server cancels its response on user speech while the client believes it owns interruptions.
|
Treating One thing worth pairing with it: once an uninterruptible speech is legitimately possible here, Both are independent of which approach fixes #6635 (they reproduce today with a pipeline agent and |
| # create_response=False leaves the reply to the client: client-side turn taking | ||
| turn_detection=resolved_turn_detection is not None | ||
| and resolved_turn_detection.create_response is not False, | ||
| can_disable_turn_detection=not is_given(turn_detection), |
There was a problem hiding this comment.
turn_detection is given when using server_vad (create_response=False, interrupt_response=False,) VAD, but its still client driven turn taking, so I think can_disable_turn_detection should be True not False when create_response=False?
There was a problem hiding this comment.
can_disable_turn_detection is true when turn_detection is not specified, it's not used if turn_detection is already False.
There was a problem hiding this comment.
We have turn_detection = ServerVad() , i.e. specified, and have client controller turn detection (c.f. on #6635 (comment) "Note — why not LiveKit "manual" turn detection with no VAD" for why)
Which means I think can_disable_turn_detection = not isGiven(True) = False
can_disable_turn_detection: bool = False
"""Whether server-side turn detection can be disabled for a session so the client drives
turn-taking. Set by plugins that implementsession(turn_detection_disabled=True)."""
Is can_disable_turn_detection = False problematic for addressing #6635 I wonder? I do not fully understand that flag, but I desire our own application code to control turn taking via RPC events, not the OpenAI server deciding when to generate replies and interrupt, so it sounds like I want it to be True to me?
There was a problem hiding this comment.
can_disable_turn_detection means if the framework can automatically disable the server turn detection fully if a client turn detection is specified.
in your case, turn_detection = ServerVad() means we shouldn't change your config. and in this pr with create_response True, the cap.turn_detection is already set to False. nothing needed from can_disable_turn_detection
There was a problem hiding this comment.
@bml1g12 since you mentioned the flag is hard to place, here is your exact config traced through this PR — it should do what you want, and can_disable_turn_detection=False is the right value for you rather than a problem.
With turn_detection=ServerVad(create_response=False, interrupt_response=False):
capabilities.turn_detectionbecomes False, because this PR makes itresolved_turn_detection is not None and resolved_turn_detection.create_response is not False. (Small slip in the comment above — it'screate_responseFalse that flips the capability off, not True.)AgentActivity._resolve_rt_turn_detection_enabled()returns on its first branch whencaps.turn_detectionis False, socan_disable_turn_detectionis never read. That's what @longcw means by "nothing needed from it" — it only gates whether the framework may switch the server's turn detection off for you, and there is nothing left to switch off._rt_turn_detection_enabledis therefore False, so the two places that used to reject your setup no longer fire: theValueErrorat construction (agent_activity.py:236) and thesay()override that forcedallow_interruptionsback toNOT_GIVEN(agent_activity.py:1410).allow_interruptions=Falseis honoured, andsay(..., allow_interruptions=False)keeps its value.
And because can_disable_turn_detection is False, the framework leaves the ServerVad config you passed exactly as you set it — with it True the framework would consider itself free to turn your server VAD off, which is the opposite of what you want, since you rely on the server VAD to keep committing and transcribing while your own code decides when to reply.
Worth keeping the interrupt_response=False in there as this PR's new warning suggests: with create_response=False alone the server still cancels its own response on user speech, which would cut a reply short even though your app never asked for it.
There was a problem hiding this comment.
I see thanks for the detailed explanation, I misunderstood what the parameter can_disable_turn_detection meant
Server VAD with
create_response=Falsestill commits and transcribes the user audio, but the reply is the client's call, so the session no longer reports server-side turn detection andallow_interruptions=Falseis honored.Fixes #6635