mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-09 22:31:41 +00:00
fix(realtime): normalize Vertex AI nested turn_detection and unify session.created guardrail ordering
- Vertex AI _build_vertex_ai_setup_config now lifts nested audio.input.turn_detection to the top level before calling map_openai_params, mirroring the parent GeminiRealtimeConfig behavior. Without this, guardrail-injected create_response: False was silently dropped for GA-protocol Vertex AI clients. - realtime_streaming session.created handling now sends the (possibly re-typed) event first and then triggers the guardrail turn-detection update for both first and duplicate cases, removing the inconsistent guardrail-then-event ordering for duplicates. Co-authored-by: Yassin Kortam <yassin@berri.ai>
This commit is contained in:
parent
8e6fe6c8ad
commit
76225f35b1
2 changed files with 24 additions and 8 deletions
|
|
@ -525,7 +525,10 @@ class RealTimeStreaming:
|
|||
else [transformed_response]
|
||||
)
|
||||
for event in events:
|
||||
if isinstance(event, dict) and event.get("type") == "session.created":
|
||||
is_session_created_event = (
|
||||
isinstance(event, dict) and event.get("type") == "session.created"
|
||||
)
|
||||
if is_session_created_event:
|
||||
if self._session_created_sent_to_client:
|
||||
# A synthetic session.created (with placeholder defaults) was
|
||||
# already forwarded to the client when we connected. The
|
||||
|
|
@ -535,16 +538,14 @@ class RealTimeStreaming:
|
|||
# `session.updated` so the client learns the corrected
|
||||
# configuration without seeing two `session.created` events.
|
||||
event = {**event, "type": "session.updated"}
|
||||
await self._maybe_send_guardrail_turn_detection_update()
|
||||
else:
|
||||
self._session_created_sent_to_client = True
|
||||
event_str = json.dumps(event)
|
||||
## For audio/VAD guardrail path: forward session.created first, then inject.
|
||||
if (
|
||||
isinstance(event, dict)
|
||||
and event.get("type") == "session.created"
|
||||
and self._has_audio_transcription_guardrails()
|
||||
):
|
||||
## For audio/VAD guardrail path: forward the (possibly re-typed)
|
||||
## session.created first, then inject the guardrail turn-detection
|
||||
## update. Handling first and duplicate session.created via the same
|
||||
## path keeps the event-then-guardrail ordering consistent.
|
||||
if is_session_created_event and self._has_audio_transcription_guardrails():
|
||||
self.store_message(event_str)
|
||||
await self.websocket.send_text(event_str)
|
||||
await self._maybe_send_guardrail_turn_detection_update()
|
||||
|
|
|
|||
|
|
@ -155,6 +155,21 @@ class VertexAIRealtimeConfig(GeminiRealtimeConfig):
|
|||
|
||||
def _build_vertex_ai_setup_config(self, model: str, session_params: dict) -> dict:
|
||||
"""Build Vertex AI setup configuration with proper model path and defaults."""
|
||||
# Normalize ``turn_detection`` to the top level so map_openai_params
|
||||
# picks it up whether the client used the flat beta shape or the
|
||||
# GA nested shape (session.audio.input.turn_detection). Without
|
||||
# this, guardrail-injected ``create_response: False`` would be
|
||||
# silently dropped for GA clients because map_openai_params only
|
||||
# looks at top-level keys.
|
||||
extracted_turn_detection = self._extract_turn_detection(session_params)
|
||||
if (
|
||||
extracted_turn_detection is not None
|
||||
and "turn_detection" not in session_params
|
||||
):
|
||||
session_params = {
|
||||
**session_params,
|
||||
"turn_detection": extracted_turn_detection,
|
||||
}
|
||||
setup_config = self.map_openai_params(
|
||||
optional_params={}, non_default_params=session_params
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue