fix(langchain): allow Gemini 3 models to use ProviderStrategy with tools (#34464)

This commit is contained in:
Théo Deschamps
2026-02-19 03:14:16 +01:00
committed by GitHub
parent 5c6f8fe0a6
commit 83f81d65af
2 changed files with 50 additions and 3 deletions

View File

@@ -495,9 +495,14 @@ def _supports_provider_strategy(
if (
model_profile is not None
and model_profile.get("structured_output")
# We make an exception for Gemini models, which currently do not support
# simultaneous tool use with structured output
and not (tools and isinstance(model_name, str) and "gemini" in model_name.lower())
# We make an exception for Gemini < 3-series models, which currently do not support
# simultaneous tool use with structured output; 3-series can.
and not (
tools
and isinstance(model_name, str)
and "gemini" in model_name.lower()
and "gemini-3" not in model_name.lower()
)
):
return True

View File

@@ -16,6 +16,7 @@ from pydantic import BaseModel, Field
from typing_extensions import TypedDict
from langchain.agents import create_agent
from langchain.agents.factory import _supports_provider_strategy
from langchain.agents.middleware.types import (
AgentMiddleware,
ModelCallResult,
@@ -897,3 +898,44 @@ def test_union_of_types() -> None:
assert response["structured_response"] == EXPECTED_WEATHER_PYDANTIC
assert len(response["messages"]) == 5
class TestSupportsProviderStrategy:
"""Unit tests for `_supports_provider_strategy`."""
@staticmethod
def _make_structured_model(model_name: str):
class GeminiTestChatModel(GenericFakeChatModel):
model_name: str
return GeminiTestChatModel(
messages=iter(
[
AIMessage(content="test-response"),
]
),
profile={"structured_output": True},
model_name=model_name,
)
def test_blocks_gemini_v2_with_tools(self) -> None:
"""Gemini 2 series models cannot use provider strategy with tools."""
model = self._make_structured_model("gemini-2.5-flash")
assert not _supports_provider_strategy(model, tools=[get_weather])
def test_allows_gemini_v3_with_tools(self) -> None:
"""Gemini 3 series models support structured output alongside tools."""
model = self._make_structured_model("gemini-3-pro-preview")
assert _supports_provider_strategy(model, tools=[get_weather])
@pytest.mark.parametrize(
"alias",
[
"gemini-flash-latest",
"gemini-flash-lite-latest",
],
)
def test_blocks_gemini_latest_aliases(self, alias: str) -> None:
"""Latest aliases stay blocked until they point to Gemini 3."""
model = self._make_structured_model(alias)
assert not _supports_provider_strategy(model, tools=[get_weather])