Skip to content

Commit ecc31c0

Browse files
committed
run autoformatter per pr comment
1 parent 8071903 commit ecc31c0

2 files changed

Lines changed: 47 additions & 16 deletions

File tree

src/google/adk/models/gemini_llm_connection.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -122,19 +122,15 @@ async def send_content(self, content: types.Content):
122122
is_gemini_api = self._api_backend == GoogleLLMVariant.GEMINI_API
123123

124124
# Route via send_realtime_input if audio is active OR if targeting 3.1 API
125-
if self._audio_active or (is_gemini_31 and is_gemini_api):
125+
if (self._audio_active or (is_gemini_31 and is_gemini_api)) and all(
126+
isinstance(part.text, str) for part in content.parts
127+
):
126128
logger.debug(
127129
'Routing text via send_realtime_input %s',
128130
content,
129131
)
130-
has_text = False
131132
for part in content.parts:
132-
if isinstance(part.text, str):
133-
await self._gemini_session.send_realtime_input(text=part.text)
134-
has_text = True
135-
136-
if not has_text:
137-
logger.warning('Encountered unsupported content in send_content')
133+
await self._gemini_session.send_realtime_input(text=part.text)
138134
else:
139135
logger.debug('Sending LLM new content %s', content)
140136
await self._gemini_session.send(
@@ -161,9 +157,13 @@ async def send_realtime(self, input: RealtimeInput):
161157
# As of now, Gemini 3.1 Flash Live is only available in Gemini API, not
162158
# Vertex AI.
163159
if is_gemini_31 and is_gemini_api:
164-
if isinstance(input.mime_type, str) and input.mime_type.startswith('audio/'):
160+
if isinstance(input.mime_type, str) and input.mime_type.startswith(
161+
'audio/'
162+
):
165163
await self._gemini_session.send_realtime_input(audio=input)
166-
elif isinstance(input.mime_type, str) and input.mime_type.startswith('image/'):
164+
elif isinstance(input.mime_type, str) and input.mime_type.startswith(
165+
'image/'
166+
):
167167
await self._gemini_session.send_realtime_input(video=input)
168168
else:
169169
logger.warning(
@@ -172,9 +172,13 @@ async def send_realtime(self, input: RealtimeInput):
172172
input.mime_type,
173173
)
174174
else:
175-
if isinstance(input.mime_type, str) and input.mime_type.startswith('video/'):
175+
if isinstance(input.mime_type, str) and input.mime_type.startswith(
176+
'video/'
177+
):
176178
await self._gemini_session.send_realtime_input(video=input)
177-
elif isinstance(input.mime_type, str) and input.mime_type.startswith('audio/'):
179+
elif isinstance(input.mime_type, str) and input.mime_type.startswith(
180+
'audio/'
181+
):
178182
await self._gemini_session.send_realtime_input(audio=input)
179183
else:
180184
await self._gemini_session.send_realtime_input(media=input)

tests/unittests/models/test_gemini_llm_connection.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,11 @@ async def test_send_history(gemini_connection, mock_gemini_session):
112112
@pytest.mark.asyncio
113113
async def test_send_content_text(gemini_connection, mock_gemini_session):
114114
"""Test send_content with text content when audio is inactive.
115-
115+
116116
Note: gemini_connection._audio_active is False by default.
117117
"""
118118
assert gemini_connection._audio_active is False
119-
119+
120120
content = types.Content(
121121
role='user', parts=[types.Part.from_text(text='Hello')]
122122
)
@@ -131,10 +131,12 @@ async def test_send_content_text(gemini_connection, mock_gemini_session):
131131

132132

133133
@pytest.mark.asyncio
134-
async def test_send_content_text_audio_active(gemini_connection, mock_gemini_session):
134+
async def test_send_content_text_audio_active(
135+
gemini_connection, mock_gemini_session
136+
):
135137
"""Test send_content routes to send_realtime_input when audio is active."""
136138
gemini_connection._audio_active = True
137-
139+
138140
content = types.Content(
139141
role='user', parts=[types.Part.from_text(text='Hello')]
140142
)
@@ -145,6 +147,31 @@ async def test_send_content_text_audio_active(gemini_connection, mock_gemini_ses
145147
mock_gemini_session.send.assert_not_called()
146148

147149

150+
@pytest.mark.asyncio
151+
async def test_send_content_mixed_audio_active(
152+
gemini_connection, mock_gemini_session, test_blob
153+
):
154+
"""Test send_content falls back to LiveClientContent for mixed modalities."""
155+
gemini_connection._audio_active = True
156+
157+
content = types.Content(
158+
role='user',
159+
parts=[
160+
types.Part.from_text(text='Hello'),
161+
types.Part(inline_data=test_blob)
162+
]
163+
)
164+
165+
await gemini_connection.send_content(content)
166+
167+
mock_gemini_session.send.assert_called_once()
168+
call_args = mock_gemini_session.send.call_args[1]
169+
assert 'input' in call_args
170+
assert call_args['input'].turns == [content]
171+
assert call_args['input'].turn_complete is True
172+
mock_gemini_session.send_realtime_input.assert_not_called()
173+
174+
148175
@pytest.mark.asyncio
149176
async def test_send_content_function_response(
150177
gemini_connection, mock_gemini_session

0 commit comments

Comments
 (0)