feat: Stop using the obsolete Gemini 1.x / Gemini 2+ model-id check in ADK
Gemini 1.x is fully deprecated, so sorting Gemini model ids into "1.x" and "or 2.0+" buckets no longer buys anything. Non-Gemini ids are unaffected: they still raise error. PiperOrigin-RevId: 960655458
This commit is contained in:
committed by
Copybara-Service
parent
5835f5a4e5
commit
745de0ac13
@@ -19,7 +19,7 @@ from typing_extensions import override
|
||||
|
||||
from ..agents.invocation_context import InvocationContext
|
||||
from ..models.llm_request import LlmRequest
|
||||
from ..utils.model_name_utils import is_gemini_eap_or_2_or_above
|
||||
from ..utils.model_name_utils import is_gemini_model
|
||||
from ..utils.model_name_utils import is_gemini_model_id_check_disabled
|
||||
from .base_code_executor import BaseCodeExecutor
|
||||
from .code_execution_utils import CodeExecutionInput
|
||||
@@ -29,7 +29,7 @@ from .code_execution_utils import CodeExecutionResult
|
||||
class BuiltInCodeExecutor(BaseCodeExecutor):
|
||||
"""A code executor that uses the Model's built-in code executor.
|
||||
|
||||
Currently only supports Gemini 2.0+ models, but will be expanded to
|
||||
Currently only supports Gemini models, but will be expanded to
|
||||
other models.
|
||||
"""
|
||||
|
||||
@@ -44,9 +44,9 @@ class BuiltInCodeExecutor(BaseCodeExecutor):
|
||||
pass
|
||||
|
||||
def process_llm_request(self, llm_request: LlmRequest) -> None:
|
||||
"""Pre-process the LLM request for Gemini 2.0+ models to use the code execution tool."""
|
||||
"""Pre-process the LLM request for Gemini models to use the code execution tool."""
|
||||
model_check_disabled = is_gemini_model_id_check_disabled()
|
||||
if is_gemini_eap_or_2_or_above(llm_request.model) or model_check_disabled:
|
||||
if is_gemini_model(llm_request.model) or model_check_disabled:
|
||||
llm_request.config = llm_request.config or types.GenerateContentConfig()
|
||||
llm_request.config.tools = llm_request.config.tools or []
|
||||
llm_request.config.tools.append(
|
||||
|
||||
@@ -19,7 +19,7 @@ from __future__ import annotations
|
||||
from pydantic import BaseModel
|
||||
from pydantic import ConfigDict
|
||||
|
||||
from ..utils.model_name_utils import is_gemini_eap_or_2_or_above
|
||||
from ..utils.model_name_utils import is_gemini_model
|
||||
from ..utils.variant_utils import get_google_llm_variant
|
||||
from ..utils.variant_utils import GoogleLLMVariant
|
||||
|
||||
@@ -44,7 +44,7 @@ def gemini_output_schema_and_tools(model_name: str) -> bool:
|
||||
"""
|
||||
return (
|
||||
get_google_llm_variant() == GoogleLLMVariant.VERTEX_AI
|
||||
and is_gemini_eap_or_2_or_above(model_name)
|
||||
and is_gemini_model(model_name)
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ from typing import TYPE_CHECKING
|
||||
from google.genai import types
|
||||
from typing_extensions import override
|
||||
|
||||
from ..utils.model_name_utils import is_gemini_1_model
|
||||
from ..utils.model_name_utils import is_gemini_model
|
||||
from ..utils.model_name_utils import is_gemini_model_id_check_disabled
|
||||
from .base_tool import BaseTool
|
||||
@@ -30,15 +29,13 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
class EnterpriseWebSearchTool(BaseTool):
|
||||
"""A Gemini 2+ built-in tool using web grounding for Enterprise compliance.
|
||||
"""A Gemini built-in tool using web grounding for Enterprise compliance.
|
||||
|
||||
NOTE: This tool is not the same as Vertex AI Search, which is used to be
|
||||
called "Enterprise Search".
|
||||
|
||||
See the documentation for more details:
|
||||
https://cloud.google.com/vertex-ai/generative-ai/docs/grounding/web-grounding-enterprise.
|
||||
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
@@ -60,11 +57,6 @@ class EnterpriseWebSearchTool(BaseTool):
|
||||
llm_request.config.tools = llm_request.config.tools or []
|
||||
|
||||
if is_gemini_model(llm_request.model) or model_check_disabled:
|
||||
if is_gemini_1_model(llm_request.model) and llm_request.config.tools:
|
||||
raise ValueError(
|
||||
'Enterprise Web Search tool cannot be used with other tools in'
|
||||
' Gemini 1.x.'
|
||||
)
|
||||
llm_request.config.tools.append(
|
||||
types.Tool(enterprise_web_search=types.EnterpriseWebSearch())
|
||||
)
|
||||
|
||||
@@ -19,7 +19,6 @@ from typing import TYPE_CHECKING
|
||||
from google.genai import types
|
||||
from typing_extensions import override
|
||||
|
||||
from ..utils.model_name_utils import is_gemini_1_model
|
||||
from ..utils.model_name_utils import is_gemini_model
|
||||
from ..utils.model_name_utils import is_gemini_model_id_check_disabled
|
||||
from .base_tool import BaseTool
|
||||
@@ -30,7 +29,7 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
class GoogleMapsGroundingTool(BaseTool):
|
||||
"""A built-in tool that is automatically invoked by Gemini 2 models to ground query results with Google Maps.
|
||||
"""A built-in tool that is automatically invoked by Gemini models to ground query results with Google Maps.
|
||||
|
||||
This tool operates internally within the model and does not require or perform
|
||||
local code execution.
|
||||
@@ -53,11 +52,7 @@ class GoogleMapsGroundingTool(BaseTool):
|
||||
model_check_disabled = is_gemini_model_id_check_disabled()
|
||||
llm_request.config = llm_request.config or types.GenerateContentConfig()
|
||||
llm_request.config.tools = llm_request.config.tools or []
|
||||
if is_gemini_1_model(llm_request.model):
|
||||
raise ValueError(
|
||||
'Google Maps grounding tool cannot be used with Gemini 1.x models.'
|
||||
)
|
||||
elif is_gemini_model(llm_request.model) or model_check_disabled:
|
||||
if is_gemini_model(llm_request.model) or model_check_disabled:
|
||||
llm_request.config.tools.append(
|
||||
types.Tool(google_maps=types.GoogleMaps())
|
||||
)
|
||||
|
||||
@@ -20,7 +20,6 @@ from google.genai import types
|
||||
from typing_extensions import override
|
||||
|
||||
from ..utils.model_name_utils import _is_managed_agent
|
||||
from ..utils.model_name_utils import is_gemini_1_model
|
||||
from ..utils.model_name_utils import is_gemini_model
|
||||
from ..utils.model_name_utils import is_gemini_model_id_check_disabled
|
||||
from .base_tool import BaseTool
|
||||
@@ -72,15 +71,7 @@ class GoogleSearchTool(BaseTool):
|
||||
model_check_disabled = is_gemini_model_id_check_disabled()
|
||||
llm_request.config = llm_request.config or types.GenerateContentConfig()
|
||||
llm_request.config.tools = llm_request.config.tools or []
|
||||
if is_gemini_1_model(llm_request.model):
|
||||
if llm_request.config.tools:
|
||||
raise ValueError(
|
||||
'Google search tool cannot be used with other tools in Gemini 1.x.'
|
||||
)
|
||||
llm_request.config.tools.append(
|
||||
types.Tool(google_search_retrieval=types.GoogleSearchRetrieval())
|
||||
)
|
||||
elif (
|
||||
if (
|
||||
is_gemini_model(llm_request.model)
|
||||
or model_check_disabled
|
||||
or _is_managed_agent(llm_request)
|
||||
|
||||
@@ -24,7 +24,7 @@ from typing import TYPE_CHECKING
|
||||
from google.genai import types
|
||||
from typing_extensions import override
|
||||
|
||||
from ...utils.model_name_utils import is_gemini_eap_or_2_or_above
|
||||
from ...utils.model_name_utils import is_gemini_model
|
||||
from ...utils.model_name_utils import is_gemini_model_id_check_disabled
|
||||
from ..tool_context import ToolContext
|
||||
from .base_retrieval_tool import BaseRetrievalTool
|
||||
@@ -64,9 +64,9 @@ class VertexAiRagRetrieval(BaseRetrievalTool):
|
||||
tool_context: ToolContext,
|
||||
llm_request: LlmRequest,
|
||||
) -> None:
|
||||
# Use Gemini built-in Vertex AI RAG tool for Gemini 2 models.
|
||||
# Use Gemini built-in Vertex AI RAG tool for Gemini models.
|
||||
model_check_disabled = is_gemini_model_id_check_disabled()
|
||||
if is_gemini_eap_or_2_or_above(llm_request.model) or model_check_disabled:
|
||||
if is_gemini_model(llm_request.model) or model_check_disabled:
|
||||
llm_request.config = (
|
||||
types.GenerateContentConfig()
|
||||
if not llm_request.config
|
||||
|
||||
@@ -22,7 +22,6 @@ from google.genai import types
|
||||
from typing_extensions import override
|
||||
|
||||
from ..agents.readonly_context import ReadonlyContext
|
||||
from ..utils.model_name_utils import is_gemini_1_model
|
||||
from ..utils.model_name_utils import is_gemini_model
|
||||
from ..utils.model_name_utils import is_gemini_model_id_check_disabled
|
||||
from .base_tool import BaseTool
|
||||
@@ -147,12 +146,6 @@ class VertexAiSearchTool(BaseTool):
|
||||
llm_request.config.tools = llm_request.config.tools or []
|
||||
|
||||
if is_gemini_model(llm_request.model) or model_check_disabled:
|
||||
if is_gemini_1_model(llm_request.model) and llm_request.config.tools:
|
||||
raise ValueError(
|
||||
'Vertex AI search tool cannot be used with other tools in Gemini'
|
||||
' 1.x.'
|
||||
)
|
||||
|
||||
# Build the search config (can be overridden by subclasses)
|
||||
vertex_ai_search_config = self._build_vertex_ai_search_config(
|
||||
tool_context
|
||||
|
||||
@@ -22,6 +22,7 @@ from typing import TYPE_CHECKING
|
||||
|
||||
from packaging.version import InvalidVersion
|
||||
from packaging.version import Version
|
||||
from typing_extensions import deprecated
|
||||
|
||||
from .env_utils import is_env_enabled
|
||||
|
||||
@@ -106,6 +107,10 @@ def is_gemini_model(model_string: Optional[str]) -> bool:
|
||||
return re.match(r'^gemini-', model_name) is not None
|
||||
|
||||
|
||||
@deprecated(
|
||||
'ADK no longer distinguishes Gemini versions internally, because Gemini'
|
||||
' 1.x is fully deprecated. Use is_gemini_model instead.'
|
||||
)
|
||||
def is_gemini_1_model(model_string: Optional[str]) -> bool:
|
||||
"""Check if the model is a Gemini 1.x model using regex patterns.
|
||||
|
||||
@@ -122,6 +127,10 @@ def is_gemini_1_model(model_string: Optional[str]) -> bool:
|
||||
return re.match(r'^gemini-1\.\d+', model_name) is not None
|
||||
|
||||
|
||||
@deprecated(
|
||||
'ADK no longer distinguishes Gemini versions internally, because Gemini'
|
||||
' 1.x is fully deprecated. Use is_gemini_model instead.'
|
||||
)
|
||||
def is_gemini_eap_or_2_or_above(model_string: Optional[str]) -> bool:
|
||||
"""Check if the model is a Gemini EAP or a Gemini 2.0+ model.
|
||||
|
||||
@@ -166,7 +175,8 @@ def _is_gemini_eap_model(model_string: Optional[str]) -> bool:
|
||||
followed by a numeric suffix, e.g. ``gemini-flash-early-exp`` or
|
||||
``gemini-flash-early-exp3``. ``<variant>`` is one or more
|
||||
alphanumeric/underscore segments separated by ``-`` (e.g. ``flash``,
|
||||
``pro``, ``flash-lite``).
|
||||
``pro``, ``flash-lite``), and is optional: variant-less EAP ids such as
|
||||
``gemini-early-exp`` are also matched.
|
||||
|
||||
Args:
|
||||
model_string: Either a simple model name or path-based model name.
|
||||
@@ -179,7 +189,9 @@ def _is_gemini_eap_model(model_string: Optional[str]) -> bool:
|
||||
|
||||
model_name = extract_model_name(model_string)
|
||||
return (
|
||||
re.match(r'^gemini-[a-z0-9_]+(?:-[a-z0-9_]+)*-early-exp\d*$', model_name)
|
||||
re.match(
|
||||
r'^gemini-(?:[a-z0-9_]+(?:-[a-z0-9_]+)*-)?early-exp\d*$', model_name
|
||||
)
|
||||
is not None
|
||||
)
|
||||
|
||||
|
||||
@@ -84,15 +84,15 @@ def test_process_llm_request_gemini_2_model_with_existing_tools(
|
||||
)
|
||||
|
||||
|
||||
def test_process_llm_request_non_gemini_2_model(
|
||||
def test_process_llm_request_non_gemini_model(
|
||||
built_in_executor: BuiltInCodeExecutor,
|
||||
):
|
||||
"""Tests that a ValueError is raised for non-Gemini 2 models."""
|
||||
llm_request = LlmRequest(model="gemini-1.5-flash")
|
||||
"""Tests that a ValueError is raised for non-Gemini models."""
|
||||
llm_request = LlmRequest(model="claude-3-sonnet")
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
built_in_executor.process_llm_request(llm_request)
|
||||
assert (
|
||||
"Gemini code execution tool is not supported for model gemini-1.5-flash"
|
||||
"Gemini code execution tool is not supported for model claude-3-sonnet"
|
||||
in str(excinfo.value)
|
||||
)
|
||||
|
||||
|
||||
@@ -126,7 +126,6 @@ def test_fallback_grants_a_gemini_named_model_and_warns(
|
||||
('bare-model', '1'), # Not a Gemini id at all.
|
||||
('gemini-2.5-pro', '0'), # Not on Vertex AI.
|
||||
('gemini-2.5-pro', None), # Not on Vertex AI.
|
||||
('gemini-1.5-pro', '1'), # Predates Gemini 2.
|
||||
],
|
||||
)
|
||||
def test_fallback_stays_quiet_when_it_denies(
|
||||
@@ -186,7 +185,7 @@ def test_subclass_can_override_a_capability():
|
||||
('gemini-2.5-flash', '1', True),
|
||||
('gemini-2.5-pro', '0', False),
|
||||
('gemini-2.5-pro', None, False),
|
||||
('gemini-1.5-pro', '1', False),
|
||||
('gemini-early-exp', '1', True),
|
||||
],
|
||||
)
|
||||
def test_gemini_output_schema_and_tools(
|
||||
@@ -195,7 +194,7 @@ def test_gemini_output_schema_and_tools(
|
||||
enterprise_mode: str | None,
|
||||
expected: bool,
|
||||
) -> None:
|
||||
"""Gemini pairs schema with tools only on Vertex AI for Gemini 2+.
|
||||
"""Gemini pairs schema with tools only on Vertex AI.
|
||||
|
||||
Declaring the capability itself, it never reaches the fallback on ``BaseLlm``
|
||||
and so is never nagged to migrate.
|
||||
@@ -227,7 +226,7 @@ def test_gemini_capabilities_follow_model_reassignment(
|
||||
) -> None:
|
||||
"""BaseLlm is mutable, so a reassigned model must be re-resolved."""
|
||||
monkeypatch.setenv('GOOGLE_GENAI_USE_ENTERPRISE', '1')
|
||||
gemini = Gemini(model='gemini-1.5-pro')
|
||||
gemini = Gemini(model='not-a-gemini-model')
|
||||
assert not gemini.capabilities.output_schema_and_tools
|
||||
|
||||
gemini.model = 'gemini-2.5-pro'
|
||||
|
||||
@@ -24,12 +24,12 @@ def noop_tool(x: str) -> str:
|
||||
return x
|
||||
|
||||
|
||||
def test_vertex_rag_retrieval_for_gemini_1_x():
|
||||
def test_vertex_rag_retrieval_for_non_gemini():
|
||||
responses = [
|
||||
'response1',
|
||||
]
|
||||
mockModel = testing_utils.MockModel.create(responses=responses)
|
||||
mockModel.model = 'gemini-1.5-pro'
|
||||
mockModel.model = 'claude-3-sonnet'
|
||||
|
||||
# Calls the first time.
|
||||
agent = Agent(
|
||||
@@ -61,12 +61,12 @@ def test_vertex_rag_retrieval_for_gemini_1_x():
|
||||
assert mockModel.requests[0].tools_dict['rag_retrieval'] is not None
|
||||
|
||||
|
||||
def test_vertex_rag_retrieval_for_gemini_1_x_with_another_function_tool():
|
||||
def test_vertex_rag_retrieval_for_non_gemini_with_another_function_tool():
|
||||
responses = [
|
||||
'response1',
|
||||
]
|
||||
mockModel = testing_utils.MockModel.create(responses=responses)
|
||||
mockModel.model = 'gemini-1.5-pro'
|
||||
mockModel.model = 'claude-3-sonnet'
|
||||
|
||||
# Calls the first time.
|
||||
agent = Agent(
|
||||
|
||||
@@ -94,22 +94,3 @@ async def test_process_llm_request_non_gemini_with_disabled_check(monkeypatch):
|
||||
== types.EnterpriseWebSearch()
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_process_llm_request_failure_with_multiple_tools_gemini_1_models():
|
||||
tool = EnterpriseWebSearchTool()
|
||||
llm_request = LlmRequest(
|
||||
model='gemini-1.5-flash',
|
||||
config=types.GenerateContentConfig(
|
||||
tools=[
|
||||
types.Tool(google_search=types.GoogleSearch()),
|
||||
]
|
||||
),
|
||||
)
|
||||
tool_context = await _create_tool_context()
|
||||
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
await tool.process_llm_request(
|
||||
tool_context=tool_context, llm_request=llm_request
|
||||
)
|
||||
assert 'cannot be used with other tools in Gemini 1.x.' in str(exc_info.value)
|
||||
|
||||
@@ -54,61 +54,6 @@ class TestGoogleSearchTool:
|
||||
assert isinstance(google_search, GoogleSearchTool)
|
||||
assert google_search.name == 'google_search'
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_process_llm_request_with_gemini_1_model(self):
|
||||
"""Test processing LLM request with Gemini 1.x model."""
|
||||
tool = GoogleSearchTool()
|
||||
tool_context = await _create_tool_context()
|
||||
|
||||
llm_request = LlmRequest(
|
||||
model='gemini-1.5-flash', config=types.GenerateContentConfig()
|
||||
)
|
||||
|
||||
await tool.process_llm_request(
|
||||
tool_context=tool_context, llm_request=llm_request
|
||||
)
|
||||
|
||||
assert llm_request.config.tools is not None
|
||||
assert len(llm_request.config.tools) == 1
|
||||
assert llm_request.config.tools[0].google_search_retrieval is not None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_process_llm_request_with_path_based_gemini_1_model(self):
|
||||
"""Test processing LLM request with path-based Gemini 1.x model."""
|
||||
tool = GoogleSearchTool()
|
||||
tool_context = await _create_tool_context()
|
||||
|
||||
llm_request = LlmRequest(
|
||||
model='projects/265104255505/locations/us-central1/publishers/google/models/gemini-1.5-flash',
|
||||
config=types.GenerateContentConfig(),
|
||||
)
|
||||
|
||||
await tool.process_llm_request(
|
||||
tool_context=tool_context, llm_request=llm_request
|
||||
)
|
||||
|
||||
assert llm_request.config.tools is not None
|
||||
assert len(llm_request.config.tools) == 1
|
||||
assert llm_request.config.tools[0].google_search_retrieval is not None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_process_llm_request_with_gemini_1_0_model(self):
|
||||
"""Test processing LLM request with Gemini 1.0 model."""
|
||||
tool = GoogleSearchTool()
|
||||
tool_context = await _create_tool_context()
|
||||
|
||||
llm_request = LlmRequest(
|
||||
model='gemini-1.0-pro', config=types.GenerateContentConfig()
|
||||
)
|
||||
|
||||
await tool.process_llm_request(
|
||||
tool_context=tool_context, llm_request=llm_request
|
||||
)
|
||||
|
||||
assert llm_request.config.tools is not None
|
||||
assert len(llm_request.config.tools) == 1
|
||||
assert llm_request.config.tools[0].google_search_retrieval is not None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_process_llm_request_with_gemini_2_model(self):
|
||||
"""Test processing LLM request with Gemini 2.x model."""
|
||||
@@ -164,64 +109,6 @@ class TestGoogleSearchTool:
|
||||
assert len(llm_request.config.tools) == 1
|
||||
assert llm_request.config.tools[0].google_search is not None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_process_llm_request_with_gemini_1_model_and_existing_tools_raises_error(
|
||||
self,
|
||||
):
|
||||
"""Test that Gemini 1.x model with existing tools raises ValueError."""
|
||||
tool = GoogleSearchTool()
|
||||
tool_context = await _create_tool_context()
|
||||
|
||||
existing_tool = types.Tool(
|
||||
function_declarations=[
|
||||
types.FunctionDeclaration(name='test_function', description='test')
|
||||
]
|
||||
)
|
||||
|
||||
llm_request = LlmRequest(
|
||||
model='gemini-1.5-flash',
|
||||
config=types.GenerateContentConfig(tools=[existing_tool]),
|
||||
)
|
||||
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match=(
|
||||
'Google search tool cannot be used with other tools in Gemini 1.x'
|
||||
),
|
||||
):
|
||||
await tool.process_llm_request(
|
||||
tool_context=tool_context, llm_request=llm_request
|
||||
)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_process_llm_request_with_path_based_gemini_1_model_and_existing_tools_raises_error(
|
||||
self,
|
||||
):
|
||||
"""Test that path-based Gemini 1.x model with existing tools raises ValueError."""
|
||||
tool = GoogleSearchTool()
|
||||
tool_context = await _create_tool_context()
|
||||
|
||||
existing_tool = types.Tool(
|
||||
function_declarations=[
|
||||
types.FunctionDeclaration(name='test_function', description='test')
|
||||
]
|
||||
)
|
||||
|
||||
llm_request = LlmRequest(
|
||||
model='projects/265104255505/locations/us-central1/publishers/google/models/gemini-1.5-pro-preview',
|
||||
config=types.GenerateContentConfig(tools=[existing_tool]),
|
||||
)
|
||||
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match=(
|
||||
'Google search tool cannot be used with other tools in Gemini 1.x'
|
||||
),
|
||||
):
|
||||
await tool.process_llm_request(
|
||||
tool_context=tool_context, llm_request=llm_request
|
||||
)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_process_llm_request_with_gemini_2_model_and_existing_tools_succeeds(
|
||||
self,
|
||||
@@ -430,36 +317,12 @@ class TestGoogleSearchTool:
|
||||
tool = GoogleSearchTool()
|
||||
tool_context = await _create_tool_context()
|
||||
|
||||
# Test various Gemini versions
|
||||
gemini_1_models = [
|
||||
'gemini-1.0-pro',
|
||||
'gemini-1.5-flash',
|
||||
'gemini-1.5-pro',
|
||||
'gemini-1.9-experimental',
|
||||
]
|
||||
|
||||
gemini_2_models = [
|
||||
'gemini-2.0-pro',
|
||||
'gemini-2.5-flash',
|
||||
'gemini-2.5-pro',
|
||||
]
|
||||
|
||||
# Test Gemini 1.x models use google_search_retrieval
|
||||
for model in gemini_1_models:
|
||||
llm_request = LlmRequest(
|
||||
model=model, config=types.GenerateContentConfig()
|
||||
)
|
||||
|
||||
await tool.process_llm_request(
|
||||
tool_context=tool_context, llm_request=llm_request
|
||||
)
|
||||
|
||||
assert llm_request.config.tools is not None
|
||||
assert len(llm_request.config.tools) == 1
|
||||
assert llm_request.config.tools[0].google_search_retrieval is not None
|
||||
assert llm_request.config.tools[0].google_search is None
|
||||
|
||||
# Test Gemini 2.x models use google_search
|
||||
for model in gemini_2_models:
|
||||
llm_request = LlmRequest(
|
||||
model=model, config=types.GenerateContentConfig()
|
||||
|
||||
@@ -154,13 +154,13 @@ class TestUrlContextTool:
|
||||
assert llm_request.config.tools[0].url_context is not None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_process_llm_request_with_path_based_gemini_model(self):
|
||||
async def test_process_llm_request_with_path_based_gemini_eap_model(self):
|
||||
"""Test that a path-based Gemini model id is accepted."""
|
||||
tool = UrlContextTool()
|
||||
tool_context = await _create_tool_context()
|
||||
|
||||
llm_request = LlmRequest(
|
||||
model='projects/265104255505/locations/us-central1/publishers/google/models/gemini-2.5-flash',
|
||||
model='projects/265104255505/locations/global/publishers/google/models/gemini-early-exp',
|
||||
config=types.GenerateContentConfig(),
|
||||
)
|
||||
|
||||
|
||||
@@ -297,66 +297,6 @@ class TestVertexAiSearchTool:
|
||||
assert 'max_results=10' in log_message
|
||||
assert 'data_store_specs=1 spec(s): [spec_store]' in log_message
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_process_llm_request_with_gemini_1_and_other_tools_raises_error(
|
||||
self,
|
||||
):
|
||||
"""Test that Gemini 1.x with other tools raises ValueError."""
|
||||
tool = VertexAiSearchTool(data_store_id='test_data_store')
|
||||
tool_context = await _create_tool_context()
|
||||
|
||||
existing_tool = types.Tool(
|
||||
function_declarations=[
|
||||
types.FunctionDeclaration(name='test_function', description='test')
|
||||
]
|
||||
)
|
||||
|
||||
llm_request = LlmRequest(
|
||||
model='gemini-1.5-flash',
|
||||
config=types.GenerateContentConfig(tools=[existing_tool]),
|
||||
)
|
||||
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match=(
|
||||
'Vertex AI search tool cannot be used with other tools in'
|
||||
' Gemini 1.x'
|
||||
),
|
||||
):
|
||||
await tool.process_llm_request(
|
||||
tool_context=tool_context, llm_request=llm_request
|
||||
)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_process_llm_request_with_path_based_gemini_1_and_other_tools_raises_error(
|
||||
self,
|
||||
):
|
||||
"""Test that path-based Gemini 1.x with other tools raises ValueError."""
|
||||
tool = VertexAiSearchTool(data_store_id='test_data_store')
|
||||
tool_context = await _create_tool_context()
|
||||
|
||||
existing_tool = types.Tool(
|
||||
function_declarations=[
|
||||
types.FunctionDeclaration(name='test_function', description='test')
|
||||
]
|
||||
)
|
||||
|
||||
llm_request = LlmRequest(
|
||||
model='projects/265104255505/locations/us-central1/publishers/google/models/gemini-1.5-pro-preview',
|
||||
config=types.GenerateContentConfig(tools=[existing_tool]),
|
||||
)
|
||||
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match=(
|
||||
'Vertex AI search tool cannot be used with other tools in'
|
||||
' Gemini 1.x'
|
||||
),
|
||||
):
|
||||
await tool.process_llm_request(
|
||||
tool_context=tool_context, llm_request=llm_request
|
||||
)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_process_llm_request_with_non_gemini_model_raises_error(self):
|
||||
"""Test that non-Gemini model raises ValueError."""
|
||||
|
||||
@@ -121,6 +121,8 @@ class TestIsGeminiModel:
|
||||
assert is_gemini_model('gemini-1.5-flash') is True
|
||||
assert is_gemini_model('gemini-1.0-pro') is True
|
||||
assert is_gemini_model('gemini-2.5-flash') is True
|
||||
assert is_gemini_model('gemini-early-exp') is True
|
||||
assert is_gemini_model('gemini-flash-early-exp') is True
|
||||
assert is_gemini_model('claude-3-sonnet') is False
|
||||
assert is_gemini_model('gpt-4') is False
|
||||
assert is_gemini_model('llama-2') is False
|
||||
@@ -231,6 +233,8 @@ class TestIsGemini2Model:
|
||||
assert is_gemini_eap_or_2_or_above('gemini-2-pro') is True
|
||||
assert is_gemini_eap_or_2_or_above('gemini-2') is True
|
||||
assert is_gemini_eap_or_2_or_above('gemini-3.0-pro') is True
|
||||
assert is_gemini_eap_or_2_or_above('gemini-early-exp') is True
|
||||
assert is_gemini_eap_or_2_or_above('gemini-early-exp2') is True
|
||||
assert is_gemini_eap_or_2_or_above('gemini-flash-early-exp') is True
|
||||
assert is_gemini_eap_or_2_or_above('gemini-flash-early-exp3') is True
|
||||
assert is_gemini_eap_or_2_or_above('gemini-flash-lite-early-exp') is True
|
||||
@@ -285,6 +289,11 @@ class TestIsGemini2Model:
|
||||
assert is_gemini_eap_or_2_or_above('gemini-0.9-test') is False
|
||||
assert is_gemini_eap_or_2_or_above('gemini-one') is False
|
||||
|
||||
# The EAP variant is optional, but the 'early-exp' marker is not.
|
||||
assert is_gemini_eap_or_2_or_above('gemini-early') is False
|
||||
assert is_gemini_eap_or_2_or_above('gemini-early-exp-flash') is False
|
||||
assert is_gemini_eap_or_2_or_above('my-gemini-early-exp') is False
|
||||
|
||||
|
||||
class TestModelNameUtilsIntegration:
|
||||
"""Integration tests for model name utilities."""
|
||||
|
||||
@@ -56,9 +56,9 @@ def _make_litellm(model: str):
|
||||
("gemini-2.5-flash", "1", True),
|
||||
("gemini-2.5-flash", "0", False),
|
||||
("gemini-2.5-flash", None, False),
|
||||
("gemini-1.5-pro", "1", False),
|
||||
("gemini-1.5-pro", "0", False),
|
||||
("gemini-1.5-pro", None, False),
|
||||
("gemini-early-exp", "1", True),
|
||||
],
|
||||
)
|
||||
def test_can_use_output_schema_with_tools(
|
||||
|
||||
Reference in New Issue
Block a user