From b591729d720b63844f03212483b181f56e8f250f Mon Sep 17 00:00:00 2001 From: Sameer Kankute Date: Mon, 27 Apr 2026 17:20:19 +0530 Subject: [PATCH] Add new functionality behind flag --- litellm/__init__.py | 5 +++++ litellm/llms/gemini/realtime/transformation.py | 9 +++++---- .../test_gemini_realtime_transformation.py | 12 ++++++++++++ .../test_vertex_ai_realtime_transformation.py | 15 +++++++++++++++ 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/litellm/__init__.py b/litellm/__init__.py index 77fa48625d9..e9ebec17759 100644 --- a/litellm/__init__.py +++ b/litellm/__init__.py @@ -224,6 +224,11 @@ use_chat_completions_url_for_anthropic_messages: bool = bool( route_all_chat_openai_to_responses: bool = ( os.getenv("LITELLM_ROUTE_ALL_CHAT_OPENAI_TO_RESPONSES", "false").lower() == "true" ) # When True, routes all OpenAI /chat/completions requests through the Responses API bridge +# When True, Gemini/Vertex Live setup is deferred until client `session.update`. +# Default False preserves historical behavior (auto-send setup on connect). +gemini_live_defer_setup: bool = ( + os.getenv("LITELLM_GEMINI_LIVE_DEFER_SETUP", "false").lower() == "true" +) retry = True ### AUTH ### api_key: Optional[str] = None diff --git a/litellm/llms/gemini/realtime/transformation.py b/litellm/llms/gemini/realtime/transformation.py index 4e278261154..7340940bc20 100644 --- a/litellm/llms/gemini/realtime/transformation.py +++ b/litellm/llms/gemini/realtime/transformation.py @@ -5,6 +5,7 @@ This file contains the transformation logic for the Gemini realtime API. import json from typing import Any, Dict, List, Optional, Union, cast +import litellm from litellm import verbose_logger from litellm._uuid import uuid from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj @@ -1136,10 +1137,10 @@ class GeminiRealtimeConfig(BaseRealtimeConfig): } def requires_session_configuration(self) -> bool: - # Return False so we DON'T auto-send setup on connection - # Instead, setup will be sent when client sends session.update - # This allows us to include tools, instructions, etc. in the FIRST setup - return False + # Default behavior is backwards-compatible: send setup on connect. + # Opt-in to deferred setup for tool-injection flow via: + # litellm.gemini_live_defer_setup = True + return not litellm.gemini_live_defer_setup def session_configuration_request(self, model: str) -> str: """ diff --git a/tests/test_litellm/llms/gemini/realtime/test_gemini_realtime_transformation.py b/tests/test_litellm/llms/gemini/realtime/test_gemini_realtime_transformation.py index 8291d62c99b..93ff824aab7 100644 --- a/tests/test_litellm/llms/gemini/realtime/test_gemini_realtime_transformation.py +++ b/tests/test_litellm/llms/gemini/realtime/test_gemini_realtime_transformation.py @@ -369,6 +369,18 @@ def test_gemini_realtime_session_update_with_tools(): assert "parameters" in function_decl +def test_gemini_requires_session_configuration_feature_flag(monkeypatch): + config = GeminiRealtimeConfig() + + # Default behavior remains backwards-compatible (auto setup on connect) + monkeypatch.setattr(litellm, "gemini_live_defer_setup", False, raising=False) + assert config.requires_session_configuration() is True + + # Opt-in behavior: defer setup until client sends session.update + monkeypatch.setattr(litellm, "gemini_live_defer_setup", True, raising=False) + assert config.requires_session_configuration() is False + + def test_gemini_realtime_function_call_output_transformation(): """Test transformation of OpenAI function_call_output to Gemini toolResponse format.""" config = GeminiRealtimeConfig() diff --git a/tests/test_litellm/llms/vertex_ai/realtime/test_vertex_ai_realtime_transformation.py b/tests/test_litellm/llms/vertex_ai/realtime/test_vertex_ai_realtime_transformation.py index 1baaf912568..e7ce3d343ac 100644 --- a/tests/test_litellm/llms/vertex_ai/realtime/test_vertex_ai_realtime_transformation.py +++ b/tests/test_litellm/llms/vertex_ai/realtime/test_vertex_ai_realtime_transformation.py @@ -19,6 +19,7 @@ import websockets.exceptions # registers websockets.exceptions on the websocket sys.path.insert(0, os.path.abspath("../../../../..")) +import litellm from litellm.llms.vertex_ai.realtime.transformation import VertexAIRealtimeConfig # --------------------------------------------------------------------------- @@ -82,6 +83,20 @@ def test_session_configuration_request_model_format(): ) +def test_vertex_requires_session_configuration_feature_flag(monkeypatch): + cfg = VertexAIRealtimeConfig( + access_token="tok", project="my-proj", location="us-central1" + ) + + # Default remains backwards-compatible (auto setup on connect) + monkeypatch.setattr(litellm, "gemini_live_defer_setup", False, raising=False) + assert cfg.requires_session_configuration() is True + + # Opt-in deferred setup for tool-injection flow + monkeypatch.setattr(litellm, "gemini_live_defer_setup", True, raising=False) + assert cfg.requires_session_configuration() is False + + # --------------------------------------------------------------------------- # Round-trip test: text-in / text-out via RealTimeStreaming # ---------------------------------------------------------------------------