diff --git a/src/google/adk/code_executors/built_in_code_executor.py b/src/google/adk/code_executors/built_in_code_executor.py index 695f4dcb..5e0a6b94 100644 --- a/src/google/adk/code_executors/built_in_code_executor.py +++ b/src/google/adk/code_executors/built_in_code_executor.py @@ -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( diff --git a/src/google/adk/models/_capabilities.py b/src/google/adk/models/_capabilities.py index 4dc13d31..b08cbe62 100644 --- a/src/google/adk/models/_capabilities.py +++ b/src/google/adk/models/_capabilities.py @@ -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) ) diff --git a/src/google/adk/tools/enterprise_search_tool.py b/src/google/adk/tools/enterprise_search_tool.py index d035f8b4..502c77bd 100644 --- a/src/google/adk/tools/enterprise_search_tool.py +++ b/src/google/adk/tools/enterprise_search_tool.py @@ -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()) ) diff --git a/src/google/adk/tools/google_maps_grounding_tool.py b/src/google/adk/tools/google_maps_grounding_tool.py index cf350451..4621412e 100644 --- a/src/google/adk/tools/google_maps_grounding_tool.py +++ b/src/google/adk/tools/google_maps_grounding_tool.py @@ -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()) ) diff --git a/src/google/adk/tools/google_search_tool.py b/src/google/adk/tools/google_search_tool.py index 8e4b384c..8727c823 100644 --- a/src/google/adk/tools/google_search_tool.py +++ b/src/google/adk/tools/google_search_tool.py @@ -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) diff --git a/src/google/adk/tools/retrieval/vertex_ai_rag_retrieval.py b/src/google/adk/tools/retrieval/vertex_ai_rag_retrieval.py index 9e820678..a4e43974 100644 --- a/src/google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +++ b/src/google/adk/tools/retrieval/vertex_ai_rag_retrieval.py @@ -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 diff --git a/src/google/adk/tools/vertex_ai_search_tool.py b/src/google/adk/tools/vertex_ai_search_tool.py index 46104c5e..b4a087f1 100644 --- a/src/google/adk/tools/vertex_ai_search_tool.py +++ b/src/google/adk/tools/vertex_ai_search_tool.py @@ -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 diff --git a/src/google/adk/utils/model_name_utils.py b/src/google/adk/utils/model_name_utils.py index c030a4cc..a762607c 100644 --- a/src/google/adk/utils/model_name_utils.py +++ b/src/google/adk/utils/model_name_utils.py @@ -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``. ```` 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 ) diff --git a/tests/unittests/code_executors/test_built_in_code_executor.py b/tests/unittests/code_executors/test_built_in_code_executor.py index 781a6424..fe34fca7 100644 --- a/tests/unittests/code_executors/test_built_in_code_executor.py +++ b/tests/unittests/code_executors/test_built_in_code_executor.py @@ -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) ) diff --git a/tests/unittests/models/test_capabilities.py b/tests/unittests/models/test_capabilities.py index 49f8411d..8daabdbe 100644 --- a/tests/unittests/models/test_capabilities.py +++ b/tests/unittests/models/test_capabilities.py @@ -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' diff --git a/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py b/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py index fdebffbd..2509f883 100644 --- a/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py +++ b/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py @@ -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( diff --git a/tests/unittests/tools/test_enterprise_web_search_tool.py b/tests/unittests/tools/test_enterprise_web_search_tool.py index 7b28d858..becd0324 100644 --- a/tests/unittests/tools/test_enterprise_web_search_tool.py +++ b/tests/unittests/tools/test_enterprise_web_search_tool.py @@ -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) diff --git a/tests/unittests/tools/test_google_search_tool.py b/tests/unittests/tools/test_google_search_tool.py index 050f148c..01547ed2 100644 --- a/tests/unittests/tools/test_google_search_tool.py +++ b/tests/unittests/tools/test_google_search_tool.py @@ -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() diff --git a/tests/unittests/tools/test_url_context_tool.py b/tests/unittests/tools/test_url_context_tool.py index edb095ba..3d9d1434 100644 --- a/tests/unittests/tools/test_url_context_tool.py +++ b/tests/unittests/tools/test_url_context_tool.py @@ -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(), ) diff --git a/tests/unittests/tools/test_vertex_ai_search_tool.py b/tests/unittests/tools/test_vertex_ai_search_tool.py index 4ca22077..b20dd6d5 100644 --- a/tests/unittests/tools/test_vertex_ai_search_tool.py +++ b/tests/unittests/tools/test_vertex_ai_search_tool.py @@ -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.""" diff --git a/tests/unittests/utils/test_model_name_utils.py b/tests/unittests/utils/test_model_name_utils.py index 7cdc7241..b84e5c7b 100644 --- a/tests/unittests/utils/test_model_name_utils.py +++ b/tests/unittests/utils/test_model_name_utils.py @@ -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.""" diff --git a/tests/unittests/utils/test_output_schema_utils.py b/tests/unittests/utils/test_output_schema_utils.py index fdcea1bd..7f176a33 100644 --- a/tests/unittests/utils/test_output_schema_utils.py +++ b/tests/unittests/utils/test_output_schema_utils.py @@ -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(