Skip to content

Commit a5d6f1e

Browse files
seanzhougooglecopybara-github
authored andcommitted
fix: Support project-based gemini model path for BuiltInCodeExecutor and all built-in tools
This is to support model path like : projects/265104255505/locations/us-central1/publishers/google/models/gemini-2.0-flash-001" PiperOrigin-RevId: 783413351
1 parent 30d7b37 commit a5d6f1e

11 files changed

+1454
-11
lines changed

src/google/adk/code_executors/built_in_code_executor.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
from __future__ import annotations
16+
1517
from google.genai import types
1618
from typing_extensions import override
1719

1820
from ..agents.invocation_context import InvocationContext
1921
from ..models import LlmRequest
22+
from ..utils.model_name_utils import is_gemini_2_model
2023
from .base_code_executor import BaseCodeExecutor
2124
from .code_execution_utils import CodeExecutionInput
2225
from .code_execution_utils import CodeExecutionResult
@@ -39,7 +42,7 @@ def execute_code(
3942

4043
def process_llm_request(self, llm_request: LlmRequest) -> None:
4144
"""Pre-process the LLM request for Gemini 2.0+ models to use the code execution tool."""
42-
if llm_request.model and llm_request.model.startswith("gemini-2"):
45+
if is_gemini_2_model(llm_request.model):
4346
llm_request.config = llm_request.config or types.GenerateContentConfig()
4447
llm_request.config.tools = llm_request.config.tools or []
4548
llm_request.config.tools.append(

src/google/adk/tools/enterprise_search_tool.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
from google.genai import types
2020
from typing_extensions import override
2121

22+
from ..utils.model_name_utils import is_gemini_1_model
23+
from ..utils.model_name_utils import is_gemini_model
2224
from .base_tool import BaseTool
2325
from .tool_context import ToolContext
2426

@@ -47,8 +49,8 @@ async def process_llm_request(
4749
tool_context: ToolContext,
4850
llm_request: LlmRequest,
4951
) -> None:
50-
if llm_request.model and 'gemini-' in llm_request.model:
51-
if 'gemini-1' in llm_request.model and llm_request.config.tools:
52+
if is_gemini_model(llm_request.model):
53+
if is_gemini_1_model(llm_request.model) and llm_request.config.tools:
5254
raise ValueError(
5355
'Enterprise web search tool can not be used with other tools in'
5456
' Gemini 1.x.'

src/google/adk/tools/google_search_tool.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
from google.genai import types
2020
from typing_extensions import override
2121

22+
from ..utils.model_name_utils import is_gemini_1_model
23+
from ..utils.model_name_utils import is_gemini_model
2224
from .base_tool import BaseTool
2325
from .tool_context import ToolContext
2426

@@ -46,15 +48,15 @@ async def process_llm_request(
4648
) -> None:
4749
llm_request.config = llm_request.config or types.GenerateContentConfig()
4850
llm_request.config.tools = llm_request.config.tools or []
49-
if llm_request.model and 'gemini-1' in llm_request.model:
51+
if is_gemini_1_model(llm_request.model):
5052
if llm_request.config.tools:
5153
raise ValueError(
5254
'Google search tool can not be used with other tools in Gemini 1.x.'
5355
)
5456
llm_request.config.tools.append(
5557
types.Tool(google_search_retrieval=types.GoogleSearchRetrieval())
5658
)
57-
elif llm_request.model and 'gemini-' in llm_request.model:
59+
elif is_gemini_model(llm_request.model):
5860
llm_request.config.tools.append(
5961
types.Tool(google_search=types.GoogleSearch())
6062
)

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@
2424
from typing_extensions import override
2525
from vertexai.preview import rag
2626

27+
from ...utils.model_name_utils import is_gemini_2_model
2728
from ..tool_context import ToolContext
2829
from .base_retrieval_tool import BaseRetrievalTool
2930

3031
if TYPE_CHECKING:
31-
from ...models.llm_request import LlmRequest
32+
from ...models import LlmRequest
3233

3334
logger = logging.getLogger('google_adk.' + __name__)
3435

@@ -62,7 +63,7 @@ async def process_llm_request(
6263
llm_request: LlmRequest,
6364
) -> None:
6465
# Use Gemini built-in Vertex AI RAG tool for Gemini 2 models.
65-
if llm_request.model and llm_request.model.startswith('gemini-2'):
66+
if is_gemini_2_model(llm_request.model):
6667
llm_request.config = (
6768
types.GenerateContentConfig()
6869
if not llm_request.config

src/google/adk/tools/url_context_tool.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
from google.genai import types
2020
from typing_extensions import override
2121

22+
from ..utils.model_name_utils import is_gemini_1_model
23+
from ..utils.model_name_utils import is_gemini_2_model
2224
from .base_tool import BaseTool
2325
from .tool_context import ToolContext
2426

@@ -46,9 +48,9 @@ async def process_llm_request(
4648
) -> None:
4749
llm_request.config = llm_request.config or types.GenerateContentConfig()
4850
llm_request.config.tools = llm_request.config.tools or []
49-
if llm_request.model and 'gemini-1' in llm_request.model:
51+
if is_gemini_1_model(llm_request.model):
5052
raise ValueError('Url context tool can not be used in Gemini 1.x.')
51-
elif llm_request.model and 'gemini-2' in llm_request.model:
53+
elif is_gemini_2_model(llm_request.model):
5254
llm_request.config.tools.append(
5355
types.Tool(url_context=types.UrlContext())
5456
)

src/google/adk/tools/vertex_ai_search_tool.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
from google.genai import types
2121
from typing_extensions import override
2222

23+
from ..utils.model_name_utils import is_gemini_1_model
24+
from ..utils.model_name_utils import is_gemini_model
2325
from .base_tool import BaseTool
2426
from .tool_context import ToolContext
2527

@@ -86,8 +88,8 @@ async def process_llm_request(
8688
tool_context: ToolContext,
8789
llm_request: LlmRequest,
8890
) -> None:
89-
if llm_request.model and 'gemini-' in llm_request.model:
90-
if 'gemini-1' in llm_request.model and llm_request.config.tools:
91+
if is_gemini_model(llm_request.model):
92+
if is_gemini_1_model(llm_request.model) and llm_request.config.tools:
9193
raise ValueError(
9294
'Vertex AI search tool can not be used with other tools in Gemini'
9395
' 1.x.'
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Utilities for model name validation and parsing."""
16+
17+
from __future__ import annotations
18+
19+
import re
20+
from typing import Optional
21+
22+
23+
def extract_model_name(model_string: str) -> str:
24+
"""Extract the actual model name from either simple or path-based format.
25+
26+
Args:
27+
model_string: Either a simple model name like "gemini-2.5-pro" or
28+
a path-based model name like "projects/.../models/gemini-2.0-flash-001"
29+
30+
Returns:
31+
The extracted model name (e.g., "gemini-2.5-pro")
32+
"""
33+
# Pattern for path-based model names
34+
path_pattern = (
35+
r'^projects/[^/]+/locations/[^/]+/publishers/[^/]+/models/(.+)$'
36+
)
37+
match = re.match(path_pattern, model_string)
38+
if match:
39+
return match.group(1)
40+
41+
# If it's not a path-based model, return as-is (simple model name)
42+
return model_string
43+
44+
45+
def is_gemini_model(model_string: Optional[str]) -> bool:
46+
"""Check if the model is a Gemini model using regex patterns.
47+
48+
Args:
49+
model_string: Either a simple model name or path-based model name
50+
51+
Returns:
52+
True if it's a Gemini model, False otherwise
53+
"""
54+
if not model_string:
55+
return False
56+
57+
model_name = extract_model_name(model_string)
58+
return re.match(r'^gemini-', model_name) is not None
59+
60+
61+
def is_gemini_1_model(model_string: Optional[str]) -> bool:
62+
"""Check if the model is a Gemini 1.x model using regex patterns.
63+
64+
Args:
65+
model_string: Either a simple model name or path-based model name
66+
67+
Returns:
68+
True if it's a Gemini 1.x model, False otherwise
69+
"""
70+
if not model_string:
71+
return False
72+
73+
model_name = extract_model_name(model_string)
74+
return re.match(r'^gemini-1\.\d+', model_name) is not None
75+
76+
77+
def is_gemini_2_model(model_string: Optional[str]) -> bool:
78+
"""Check if the model is a Gemini 2.x model using regex patterns.
79+
80+
Args:
81+
model_string: Either a simple model name or path-based model name
82+
83+
Returns:
84+
True if it's a Gemini 2.x model, False otherwise
85+
"""
86+
if not model_string:
87+
return False
88+
89+
model_name = extract_model_name(model_string)
90+
return re.match(r'^gemini-2\.\d+', model_name) is not None

0 commit comments

Comments
 (0)