Skip to content

Commit 6aa8da2

Browse files
yinghsienwucopybara-github
authored andcommitted
feat: support speech to speech translation in Gemini Live
PiperOrigin-RevId: 914523879
1 parent 6fa256f commit 6aa8da2

7 files changed

Lines changed: 111 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
# Changelog
22

3-
## [2.2.0](https://github.com/googleapis/python-genai/compare/v2.1.0...v2.2.0) (2026-05-12)
4-
5-
6-
### Features
7-
8-
* Added missing FunctionCallResultDelta type and `arguments` field to the ArgumentDelta type ([b0131f8](https://github.com/googleapis/python-genai/commit/b0131f80c2da97926bcef00b4abef9334272ee7a))
9-
103
## [2.1.0](https://github.com/googleapis/python-genai/compare/v2.0.1...v2.1.0) (2026-05-12)
114

125

google/genai/_live_converters.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,13 @@ def _LiveConnectConfig_to_mldev(
933933
],
934934
)
935935

936+
if getv(from_object, ['stream_translation_config']) is not None:
937+
setv(
938+
parent_object,
939+
['setup', 'generationConfig', 'streamTranslationConfig'],
940+
getv(from_object, ['stream_translation_config']),
941+
)
942+
936943
return to_object
937944

938945

@@ -1113,6 +1120,12 @@ def _LiveConnectConfig_to_vertex(
11131120
[item for item in getv(from_object, ['safety_settings'])],
11141121
)
11151122

1123+
if getv(from_object, ['stream_translation_config']) is not None:
1124+
raise ValueError(
1125+
'stream_translation_config parameter is only supported in Gemini'
1126+
' Developer API mode, not in Gemini Enterprise Agent Platform mode.'
1127+
)
1128+
11161129
return to_object
11171130

11181131

google/genai/_tokens_converters.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,13 @@ def _LiveConnectConfig_to_mldev(
474474
],
475475
)
476476

477+
if getv(from_object, ['stream_translation_config']) is not None:
478+
setv(
479+
parent_object,
480+
['setup', 'generationConfig', 'streamTranslationConfig'],
481+
getv(from_object, ['stream_translation_config']),
482+
)
483+
477484
return to_object
478485

479486

google/genai/tests/live/test_live.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1610,6 +1610,55 @@ async def test_bidi_setup_to_api_with_transparent_session_resumption(vertexai):
16101610
assert result == expected_result
16111611

16121612

1613+
@pytest.mark.parametrize('vertexai', [True, False])
1614+
@pytest.mark.asyncio
1615+
async def test_bidi_setup_to_api_with_stream_translation_config(vertexai):
1616+
api_client = mock_api_client(vertexai=vertexai)
1617+
1618+
# Test 1: Config defined using dict representation.
1619+
config_dict = {
1620+
'stream_translation_config': {
1621+
'echo_target_language': True,
1622+
'target_language_code': 'es',
1623+
},
1624+
}
1625+
1626+
with pytest_helper.exception_if_vertex(api_client, ValueError):
1627+
result = await get_connect_message(
1628+
api_client=api_client, model='test_model', config=config_dict
1629+
)
1630+
1631+
if not vertexai:
1632+
expected_result = {
1633+
'setup': {
1634+
'model': 'models/test_model',
1635+
'generationConfig': {
1636+
'streamTranslationConfig': {
1637+
'echo_target_language': True,
1638+
'target_language_code': 'es',
1639+
},
1640+
},
1641+
}
1642+
}
1643+
assert result == expected_result
1644+
1645+
# Test 2: Config defined using types.LiveConnectConfig.
1646+
config = types.LiveConnectConfig(
1647+
stream_translation_config=types.StreamTranslationConfig(
1648+
echo_target_language=True,
1649+
target_language_code='es',
1650+
)
1651+
)
1652+
1653+
with pytest_helper.exception_if_vertex(api_client, ValueError):
1654+
result = await get_connect_message(
1655+
api_client=api_client, model='test_model', config=config
1656+
)
1657+
1658+
if not vertexai:
1659+
assert result == expected_result
1660+
1661+
16131662
@pytest.mark.parametrize('vertexai', [True, False])
16141663
def test_parse_client_message_str( mock_websocket, vertexai):
16151664
session = live.AsyncSession(

google/genai/types.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19507,6 +19507,40 @@ class RealtimeInputConfigDict(TypedDict, total=False):
1950719507
RealtimeInputConfigOrDict = Union[RealtimeInputConfig, RealtimeInputConfigDict]
1950819508

1950919509

19510+
class StreamTranslationConfig(_common.BaseModel):
19511+
"""Config for stream translation."""
19512+
19513+
echo_target_language: Optional[bool] = Field(
19514+
default=None,
19515+
description="""If true, the model will generate audio when the target language is
19516+
spoken, essentially it will parrot the input. If false, we will not produce
19517+
audio for the target language.""",
19518+
)
19519+
target_language_code: Optional[str] = Field(
19520+
default=None,
19521+
description="""The target language for translation. Supported values are BCP-47
19522+
language codes (e.g. "en", "es", "fr").""",
19523+
)
19524+
19525+
19526+
class StreamTranslationConfigDict(TypedDict, total=False):
19527+
"""Config for stream translation."""
19528+
19529+
echo_target_language: Optional[bool]
19530+
"""If true, the model will generate audio when the target language is
19531+
spoken, essentially it will parrot the input. If false, we will not produce
19532+
audio for the target language."""
19533+
19534+
target_language_code: Optional[str]
19535+
"""The target language for translation. Supported values are BCP-47
19536+
language codes (e.g. "en", "es", "fr")."""
19537+
19538+
19539+
StreamTranslationConfigOrDict = Union[
19540+
StreamTranslationConfig, StreamTranslationConfigDict
19541+
]
19542+
19543+
1951019544
class LiveConnectConfig(_common.BaseModel):
1951119545
"""Session config for the API connection."""
1951219546

@@ -19645,6 +19679,9 @@ class LiveConnectConfig(_common.BaseModel):
1964519679
response.
1964619680
""",
1964719681
)
19682+
stream_translation_config: Optional[StreamTranslationConfig] = Field(
19683+
default=None, description="""Config for stream translation."""
19684+
)
1964819685

1964919686

1965019687
class LiveConnectConfigDict(TypedDict, total=False):
@@ -19763,6 +19800,9 @@ class LiveConnectConfigDict(TypedDict, total=False):
1976319800
response.
1976419801
"""
1976519802

19803+
stream_translation_config: Optional[StreamTranslationConfigDict]
19804+
"""Config for stream translation."""
19805+
1976619806

1976719807
LiveConnectConfigOrDict = Union[LiveConnectConfig, LiveConnectConfigDict]
1976819808

google/genai/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@
1313
# limitations under the License.
1414
#
1515

16-
__version__ = '2.2.0' # x-release-please-version
16+
__version__ = '2.1.0' # x-release-please-version

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ requires = ["setuptools", "wheel", "twine>=6.1.0", "packaging>=24.2", "pkginfo>=
33

44
[project]
55
name = "google-genai"
6-
version = "2.2.0"
6+
version = "2.1.0"
77
description = "GenAI Python SDK"
88
readme = "README.md"
99
license = "Apache-2.0"

0 commit comments

Comments
 (0)