Skip to content

Commit b58ce57

Browse files
google-genai-botcopybara-github
authored andcommitted
chore: Enable gemini EAP models for gemini-builtin tools
PiperOrigin-RevId: 911554133
1 parent 211e2ce commit b58ce57

6 files changed

Lines changed: 61 additions & 49 deletions

File tree

src/google/adk/code_executors/built_in_code_executor.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
from ..agents.invocation_context import InvocationContext
2121
from ..models import LlmRequest
22-
from ..utils.model_name_utils import is_gemini_2_or_above
22+
from ..utils.model_name_utils import is_gemini_eap_or_2_or_above
2323
from ..utils.model_name_utils import is_gemini_model_id_check_disabled
2424
from .base_code_executor import BaseCodeExecutor
2525
from .code_execution_utils import CodeExecutionInput
@@ -44,7 +44,7 @@ def execute_code(
4444
def process_llm_request(self, llm_request: LlmRequest) -> None:
4545
"""Pre-process the LLM request for Gemini 2.0+ models to use the code execution tool."""
4646
model_check_disabled = is_gemini_model_id_check_disabled()
47-
if is_gemini_2_or_above(llm_request.model) or model_check_disabled:
47+
if is_gemini_eap_or_2_or_above(llm_request.model) or model_check_disabled:
4848
llm_request.config = llm_request.config or types.GenerateContentConfig()
4949
llm_request.config.tools = llm_request.config.tools or []
5050
llm_request.config.tools.append(

src/google/adk/tools/retrieval/vertex_ai_rag_retrieval.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from google.genai import types
2424
from typing_extensions import override
2525

26-
from ...utils.model_name_utils import is_gemini_2_or_above
26+
from ...utils.model_name_utils import is_gemini_eap_or_2_or_above
2727
from ...utils.model_name_utils import is_gemini_model_id_check_disabled
2828
from ..tool_context import ToolContext
2929
from .base_retrieval_tool import BaseRetrievalTool
@@ -65,7 +65,7 @@ async def process_llm_request(
6565
) -> None:
6666
# Use Gemini built-in Vertex AI RAG tool for Gemini 2 models.
6767
model_check_disabled = is_gemini_model_id_check_disabled()
68-
if is_gemini_2_or_above(llm_request.model) or model_check_disabled:
68+
if is_gemini_eap_or_2_or_above(llm_request.model) or model_check_disabled:
6969
llm_request.config = (
7070
types.GenerateContentConfig()
7171
if not llm_request.config

src/google/adk/tools/url_context_tool.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@
2020
from typing_extensions import override
2121

2222
from ..utils.model_name_utils import is_gemini_1_model
23-
from ..utils.model_name_utils import is_gemini_2_or_above
24-
from ..utils.model_name_utils import is_gemini_eap_model
23+
from ..utils.model_name_utils import is_gemini_eap_or_2_or_above
2524
from ..utils.model_name_utils import is_gemini_model_id_check_disabled
2625
from .base_tool import BaseTool
2726
from .tool_context import ToolContext
@@ -53,11 +52,7 @@ async def process_llm_request(
5352
llm_request.config.tools = llm_request.config.tools or []
5453
if is_gemini_1_model(llm_request.model):
5554
raise ValueError('Url context tool cannot be used in Gemini 1.x.')
56-
elif (
57-
is_gemini_2_or_above(llm_request.model)
58-
or is_gemini_eap_model(llm_request.model)
59-
or model_check_disabled
60-
):
55+
elif is_gemini_eap_or_2_or_above(llm_request.model) or model_check_disabled:
6156
llm_request.config.tools.append(
6257
types.Tool(url_context=types.UrlContext())
6358
)

src/google/adk/utils/model_name_utils.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,18 +99,27 @@ def is_gemini_1_model(model_string: Optional[str]) -> bool:
9999
return re.match(r'^gemini-1\.\d+', model_name) is not None
100100

101101

102-
def is_gemini_2_or_above(model_string: Optional[str]) -> bool:
103-
"""Check if the model is a Gemini 2.0 or newer model using semantic versions.
102+
def is_gemini_eap_or_2_or_above(model_string: Optional[str]) -> bool:
103+
"""Check if the model is a Gemini EAP or a Gemini 2.0+ model.
104+
105+
EAP (Early Access Program) Gemini models follow a different naming
106+
convention (see ``_is_gemini_eap_model``) and do not encode a numeric
107+
version, so they are checked first. Otherwise the model name is parsed
108+
as a semantic version and is considered a match when the major version
109+
is ``>= 2``.
104110
105111
Args:
106112
model_string: Either a simple model name or path-based model name
107113
108114
Returns:
109-
True if it's a Gemini 2.0+ model, False otherwise
115+
True if it's a Gemini EAP model or a Gemini 2.0+ model, False otherwise
110116
"""
111117
if not model_string:
112118
return False
113119

120+
if _is_gemini_eap_model(model_string):
121+
return True
122+
114123
model_name = extract_model_name(model_string)
115124
if not model_name.startswith('gemini-'):
116125
return False
@@ -127,7 +136,7 @@ def is_gemini_2_or_above(model_string: Optional[str]) -> bool:
127136
return parsed_version.major >= 2
128137

129138

130-
def is_gemini_eap_model(model_string: Optional[str]) -> bool:
139+
def _is_gemini_eap_model(model_string: Optional[str]) -> bool:
131140
"""Check if the model is an Early Access Program (EAP) Gemini model.
132141
133142
Matches names of the form ``gemini-<variant>-early-exp`` optionally

src/google/adk/utils/output_schema_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from typing import Union
2424

2525
from ..models.base_llm import BaseLlm
26-
from .model_name_utils import is_gemini_2_or_above
26+
from .model_name_utils import is_gemini_eap_or_2_or_above
2727
from .variant_utils import get_google_llm_variant
2828
from .variant_utils import GoogleLLMVariant
2929

@@ -49,5 +49,5 @@ def can_use_output_schema_with_tools(model: Union[str, BaseLlm]) -> bool:
4949

5050
return (
5151
get_google_llm_variant() == GoogleLLMVariant.VERTEX_AI
52-
and is_gemini_2_or_above(model_string)
52+
and is_gemini_eap_or_2_or_above(model_string)
5353
)

tests/unittests/utils/test_model_name_utils.py

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
from google.adk.utils.model_name_utils import extract_model_name
1818
from google.adk.utils.model_name_utils import is_gemini_1_model
19-
from google.adk.utils.model_name_utils import is_gemini_2_or_above
19+
from google.adk.utils.model_name_utils import is_gemini_eap_or_2_or_above
2020
from google.adk.utils.model_name_utils import is_gemini_model
2121
from google.adk.utils.model_name_utils import is_gemini_model_id_check_disabled
2222

@@ -189,50 +189,56 @@ def test_is_gemini_1_model_edge_cases(self):
189189

190190

191191
class TestIsGemini2Model:
192-
"""Test the is_gemini_2_or_above function."""
192+
"""Test the is_gemini_eap_or_2_or_above function."""
193193

194-
def test_is_gemini_2_or_above_simple_names(self):
194+
def test_is_gemini_eap_or_2_or_above_simple_names(self):
195195
"""Test Gemini 2.0+ model detection with simple model names."""
196-
assert is_gemini_2_or_above('gemini-2.5-flash') is True
197-
assert is_gemini_2_or_above('gemini-2.5-pro') is True
198-
assert is_gemini_2_or_above('gemini-2.9-experimental') is True
199-
assert is_gemini_2_or_above('gemini-2-pro') is True
200-
assert is_gemini_2_or_above('gemini-2') is True
201-
assert is_gemini_2_or_above('gemini-3.0-pro') is True
202-
assert is_gemini_2_or_above('gemini-1.5-flash') is False
203-
assert is_gemini_2_or_above('gemini-1.0-pro') is False
204-
assert is_gemini_2_or_above('claude-3-sonnet') is False
205-
206-
def test_is_gemini_2_or_above_path_based_names(self):
196+
assert is_gemini_eap_or_2_or_above('gemini-2.5-flash') is True
197+
assert is_gemini_eap_or_2_or_above('gemini-2.5-pro') is True
198+
assert is_gemini_eap_or_2_or_above('gemini-2.9-experimental') is True
199+
assert is_gemini_eap_or_2_or_above('gemini-2-pro') is True
200+
assert is_gemini_eap_or_2_or_above('gemini-2') is True
201+
assert is_gemini_eap_or_2_or_above('gemini-3.0-pro') is True
202+
assert is_gemini_eap_or_2_or_above('gemini-flash-early-exp') is True
203+
assert is_gemini_eap_or_2_or_above('gemini-flash-early-exp3') is True
204+
assert is_gemini_eap_or_2_or_above('gemini-flash-lite-early-exp') is True
205+
assert is_gemini_eap_or_2_or_above('gemini-pro-early-exp') is True
206+
assert is_gemini_eap_or_2_or_above('gemini-1.5-flash') is False
207+
assert is_gemini_eap_or_2_or_above('gemini-1.0-pro') is False
208+
assert is_gemini_eap_or_2_or_above('claude-3-sonnet') is False
209+
210+
def test_is_gemini_eap_or_2_or_above_path_based_names(self):
207211
"""Test Gemini 2.0+ model detection with path-based model names."""
208212
gemini_2_path = 'projects/265104255505/locations/us-central1/publishers/google/models/gemini-2.5-flash'
209-
assert is_gemini_2_or_above(gemini_2_path) is True
213+
assert is_gemini_eap_or_2_or_above(gemini_2_path) is True
210214

211215
gemini_2_path_2 = 'projects/12345/locations/us-east1/publishers/google/models/gemini-2.5-pro-preview'
212-
assert is_gemini_2_or_above(gemini_2_path_2) is True
216+
assert is_gemini_eap_or_2_or_above(gemini_2_path_2) is True
213217

214218
gemini_1_path = 'projects/265104255505/locations/us-central1/publishers/google/models/gemini-1.5-flash'
215-
assert is_gemini_2_or_above(gemini_1_path) is False
219+
assert is_gemini_eap_or_2_or_above(gemini_1_path) is False
216220

217221
gemini_3_path = 'projects/12345/locations/us-east1/publishers/google/models/gemini-3.0-pro'
218-
assert is_gemini_2_or_above(gemini_3_path) is True
222+
assert is_gemini_eap_or_2_or_above(gemini_3_path) is True
219223

220-
def test_is_gemini_2_or_above_edge_cases(self):
224+
def test_is_gemini_eap_or_2_or_above_edge_cases(self):
221225
"""Test edge cases for Gemini 2.0+ model detection."""
222226
# Test with None
223-
assert is_gemini_2_or_above(None) is False
227+
assert is_gemini_eap_or_2_or_above(None) is False
224228

225229
# Test with empty string
226-
assert is_gemini_2_or_above('') is False
230+
assert is_gemini_eap_or_2_or_above('') is False
227231

228232
# Test with model names containing gemini-2 but not starting with it
229-
assert is_gemini_2_or_above('my-gemini-2.5-model') is False
230-
assert is_gemini_2_or_above('custom-gemini-2.5-flash') is False
233+
assert is_gemini_eap_or_2_or_above('my-gemini-2.5-model') is False
234+
assert is_gemini_eap_or_2_or_above('custom-gemini-2.5-flash') is False
231235

232236
# Test with invalid versions
233-
assert is_gemini_2_or_above('gemini-2.') is False # Missing version number
234-
assert is_gemini_2_or_above('gemini-0.9-test') is False
235-
assert is_gemini_2_or_above('gemini-one') is False
237+
assert (
238+
is_gemini_eap_or_2_or_above('gemini-2.') is False
239+
) # Missing version number
240+
assert is_gemini_eap_or_2_or_above('gemini-0.9-test') is False
241+
assert is_gemini_eap_or_2_or_above('gemini-one') is False
236242

237243

238244
class TestModelNameUtilsIntegration:
@@ -255,14 +261,14 @@ def test_model_classification_consistency(self):
255261
for model in test_models:
256262
# A model can only be either Gemini 1.x or Gemini 2.0+, not both
257263
if is_gemini_1_model(model):
258-
assert not is_gemini_2_or_above(
264+
assert not is_gemini_eap_or_2_or_above(
259265
model
260266
), f'Model {model} classified as both Gemini 1.x and 2.0+'
261267
assert is_gemini_model(
262268
model
263269
), f'Model {model} is Gemini 1.x but not classified as Gemini'
264270

265-
if is_gemini_2_or_above(model):
271+
if is_gemini_eap_or_2_or_above(model):
266272
assert not is_gemini_1_model(
267273
model
268274
), f'Model {model} classified as both Gemini 1.x and 2.0+'
@@ -271,7 +277,9 @@ def test_model_classification_consistency(self):
271277
), f'Model {model} is Gemini 2.0+ but not classified as Gemini'
272278

273279
# If it's neither Gemini 1.x nor 2.0+, it should not be classified as Gemini
274-
if not is_gemini_1_model(model) and not is_gemini_2_or_above(model):
280+
if not is_gemini_1_model(model) and not is_gemini_eap_or_2_or_above(
281+
model
282+
):
275283
if model and 'gemini-' not in extract_model_name(model):
276284
assert not is_gemini_model(
277285
model
@@ -312,9 +320,9 @@ def test_path_vs_simple_model_consistency(self):
312320
f'Inconsistent Gemini 1.x classification for {simple_model} vs'
313321
f' {path_model}'
314322
)
315-
assert is_gemini_2_or_above(simple_model) == is_gemini_2_or_above(
316-
path_model
317-
), (
323+
assert is_gemini_eap_or_2_or_above(
324+
simple_model
325+
) == is_gemini_eap_or_2_or_above(path_model), (
318326
f'Inconsistent Gemini 2.0+ classification for {simple_model} vs'
319327
f' {path_model}'
320328
)

0 commit comments

Comments
 (0)