From f517a8f517818f810d9f414b680f42dc1d37eda3 Mon Sep 17 00:00:00 2001 From: Ayoub Date: Tue, 27 Oct 2026 00:04:25 +0100 Subject: [PATCH] Python: Honor the requested model in non-streamed Gemini responses _get_response resolved the request model but did not pass it to _process_generate_response, which fell back to the client default when the response carried no model_version. The streaming path already falls back to the resolved model, so the same call was labelled differently depending on stream. _process_generate_response now takes the request model as a keyword-only argument and falls back to it before the client default. --- .../agent_framework_gemini/_chat_client.py | 6 ++-- .../gemini/tests/test_gemini_client.py | 32 +++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/python/packages/gemini/agent_framework_gemini/_chat_client.py b/python/packages/gemini/agent_framework_gemini/_chat_client.py index b64c9e58cf7..f2702cd0336 100644 --- a/python/packages/gemini/agent_framework_gemini/_chat_client.py +++ b/python/packages/gemini/agent_framework_gemini/_chat_client.py @@ -524,7 +524,7 @@ async def _get_response() -> ChatResponse: raise except Exception as ex: raise _wrap_gemini_error(ex) from ex - return self._process_generate_response(raw, response_format=validated.get("response_format")) + return self._process_generate_response(raw, model=model, response_format=validated.get("response_format")) return _get_response() @@ -1065,12 +1065,14 @@ def _process_generate_response( self, response: types.GenerateContentResponse, *, + model: str | None = None, response_format: type[BaseModel] | None = None, ) -> ChatResponse: """Convert a Gemini generate_content response to a framework ChatResponse. Args: response: The raw ``GenerateContentResponse`` from the Gemini API. + model: The model the request was sent to, reported when the response carries no model version. response_format: Optional Pydantic model type for structured output parsing. When provided, the response text is parsed into the given model and made available via ``ChatResponse.value``. @@ -1085,7 +1087,7 @@ def _process_generate_response( response_id=None, messages=[Message(role="assistant", contents=contents, raw_representation=candidate)], usage_details=self._parse_usage(response.usage_metadata), - model=response.model_version or self.model, + model=response.model_version or model or self.model, finish_reason=self._map_finish_reason( candidate.finish_reason.name if candidate and candidate.finish_reason else None ), diff --git a/python/packages/gemini/tests/test_gemini_client.py b/python/packages/gemini/tests/test_gemini_client.py index 873654676de..b810e2b9e09 100644 --- a/python/packages/gemini/tests/test_gemini_client.py +++ b/python/packages/gemini/tests/test_gemini_client.py @@ -548,6 +548,38 @@ async def test_get_response_model_from_response() -> None: assert response.model == "gemini-2.5-pro-002" +async def test_get_response_model_falls_back_to_configured_model() -> None: + """Falls back to the configured model when the response carries no model_version.""" + client, mock = _make_gemini_client() + raw = _make_response([_make_part(text="Hi")]) + raw.model_version = None + mock.aio.models.generate_content = AsyncMock(return_value=raw) + + response = await client.get_response(messages=[Message(role="user", contents=[Content.from_text("Hi")])]) + + assert response.model == "gemini-2.5-flash" + + +@pytest.mark.parametrize("stream", [False, True]) +async def test_get_response_reports_requested_model_on_both_paths(stream: bool) -> None: + """Without a model_version, both paths report the model requested in options, not the client default.""" + client, mock = _make_gemini_client(model="gemini-2.5-flash") + raw = _make_response([_make_part(text="Hi")]) + raw.model_version = None + mock.aio.models.generate_content = AsyncMock(return_value=raw) + mock.aio.models.generate_content_stream = AsyncMock(return_value=_async_iter([raw])) + messages = [Message(role="user", contents=[Content.from_text("Hi")])] + + if stream: + response = await client.get_response( + messages=messages, options={"model": "gemini-2.5-pro"}, stream=True + ).get_final_response() + else: + response = await client.get_response(messages=messages, options={"model": "gemini-2.5-pro"}) + + assert response.model == "gemini-2.5-pro" + + async def test_get_response_streaming_model_from_chunk() -> None: """Populates the update model from the model_version field on each chunk.""" client, mock = _make_gemini_client()