Skip to content

Commit 2896620

Browse files
authored
Merge branch 'main' into deploy-docker
2 parents 45c49cf + c843503 commit 2896620

File tree

15 files changed

+349
-23
lines changed

15 files changed

+349
-23
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Config-based Agent Sample - Learning Assistant
2+
3+
This sample demonstrates a minimal multi-agent setup with a learning assistant that delegates to specialized tutoring agents.
4+
5+
## Structure
6+
7+
- `root_agent.yaml` - Main learning assistant agent that routes questions to appropriate tutors
8+
- `code_tutor_agent.yaml` - Specialized agent for programming and coding questions
9+
- `math_tutor_agent.yaml` - Specialized agent for mathematical concepts and problems
10+
11+
## Usage
12+
13+
The root agent will automatically delegate:
14+
- Coding/programming questions → `code_tutor_agent`
15+
- Math questions → `math_tutor_agent`
16+
17+
This example shows how to create a simple multi-agent system without tools, focusing on clear delegation and specialized expertise.
18+
19+
## Sample Queries
20+
21+
### Coding Questions
22+
23+
```
24+
"How do I create a for loop in Python?"
25+
"Can you help me debug this function?"
26+
"What are the best practices for variable naming?"
27+
```
28+
29+
### Math Questions
30+
31+
```
32+
"Can you explain the quadratic formula?"
33+
"How do I solve this algebra problem: 2x + 5 = 15?"
34+
"What's the difference between mean and median?"
35+
```
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/google/adk-python/refs/heads/main/src/google/adk/agents/config_schemas/AgentConfig.json
2+
agent_class: LlmAgent
3+
name: code_tutor_agent
4+
description: Coding tutor that helps with programming concepts and questions.
5+
instruction: |
6+
You are a helpful coding tutor that specializes in teaching programming concepts.
7+
8+
Your role is to:
9+
1. Explain programming concepts clearly and simply
10+
2. Help debug code issues
11+
3. Provide code examples and best practices
12+
4. Guide students through problem-solving approaches
13+
5. Encourage good coding habits
14+
15+
Always be patient, encouraging, and provide step-by-step explanations.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/google/adk-python/refs/heads/main/src/google/adk/agents/config_schemas/AgentConfig.json
2+
agent_class: LlmAgent
3+
name: math_tutor_agent
4+
description: Math tutor that helps with mathematical concepts and problems.
5+
instruction: |
6+
You are a helpful math tutor that specializes in teaching mathematical concepts.
7+
8+
Your role is to:
9+
1. Explain mathematical concepts clearly with examples
10+
2. Help solve math problems step by step
11+
3. Provide different approaches to solving problems
12+
4. Help students understand the reasoning behind solutions
13+
5. Encourage mathematical thinking and problem-solving skills
14+
15+
Always break down complex problems into manageable steps and be patient with explanations.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/google/adk-python/refs/heads/main/src/google/adk/agents/config_schemas/AgentConfig.json
2+
agent_class: LlmAgent
3+
model: gemini-2.5-flash
4+
name: root_agent
5+
description: Learning assistant that provides tutoring in code and math.
6+
instruction: |
7+
You are a learning assistant that helps students with coding and math questions.
8+
9+
You delegate coding questions to the code_tutor_agent and math questions to the math_tutor_agent.
10+
11+
Follow these steps:
12+
1. If the user asks about programming or coding, delegate to the code_tutor_agent.
13+
2. If the user asks about math concepts or problems, delegate to the math_tutor_agent.
14+
3. Always provide clear explanations and encourage learning.
15+
sub_agents:
16+
- config_path: code_tutor_agent.yaml
17+
- config_path: math_tutor_agent.yaml

contributing/samples/oauth_calendar_agent/agent.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@
4646
# google calendar tool by adding `calendar_events_list` in the filter list
4747
client_id=oauth_client_id,
4848
client_secret=oauth_client_secret,
49-
tool_filter=["calendar_events_get"],
49+
tool_filter=["calendar_events_get", "calendar_events_update"],
50+
tool_name_prefix="google",
5051
)
5152

5253

@@ -125,7 +126,7 @@ def update_time(callback_context: CallbackContext):
125126
126127
Scenario2:
127128
User want to know the details of one of the listed calendar events.
128-
Use get_calendar_event to get the details of a calendar event.
129+
Use google_calendar_events_get to get the details of a calendar event.
129130
130131
131132
Current user:

src/google/adk/agents/llm_agent.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ class LlmAgent(BaseAgent):
130130
When not set, the agent will inherit the model from its ancestor.
131131
"""
132132

133-
config_type: ClassVar[type[BaseAgentConfig]] = LlmAgentConfig
133+
config_type: ClassVar[Type[BaseAgentConfig]] = LlmAgentConfig
134134
"""The config type for this agent."""
135135

136136
instruction: Union[str, InstructionProvider] = ''

src/google/adk/agents/sequential_agent.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from __future__ import annotations
1818

1919
from typing import AsyncGenerator
20+
from typing import ClassVar
2021
from typing import Type
2122

2223
from typing_extensions import override
@@ -33,7 +34,7 @@
3334
class SequentialAgent(BaseAgent):
3435
"""A shell agent that runs its sub-agents in sequence."""
3536

36-
config_type: Type[BaseAgentConfig] = SequentialAgentConfig
37+
config_type: ClassVar[Type[BaseAgentConfig]] = SequentialAgentConfig
3738
"""The config type for this agent."""
3839

3940
@override

src/google/adk/cli/cli_deploy.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@
1919
from typing import Optional
2020

2121
import click
22+
from packaging.version import parse
23+
24+
BASE_BUILD_IMAGE = 'python:3.11-slim'
2225

2326
_DOCKERFILE_TEMPLATE = """
24-
FROM python:3.11-slim
27+
FROM {build_image}
2528
WORKDIR /app
2629
2730
# Create a non-root user
@@ -88,7 +91,8 @@ def _get_service_option_by_adk_version(
8891
memory_uri: Optional[str],
8992
) -> str:
9093
"""Returns service option string based on adk_version."""
91-
if adk_version >= '1.3.0':
94+
parsed_version = parse(adk_version)
95+
if parsed_version >= parse('1.3.0'):
9296
session_option = (
9397
f'--session_service_uri={session_uri}' if session_uri else ''
9498
)
@@ -97,7 +101,7 @@ def _get_service_option_by_adk_version(
97101
)
98102
memory_option = f'--memory_service_uri={memory_uri}' if memory_uri else ''
99103
return f'{session_option} {artifact_option} {memory_option}'
100-
elif adk_version >= '1.2.0':
104+
elif parsed_version >= parse('1.2.0'):
101105
session_option = f'--session_db_url={session_uri}' if session_uri else ''
102106
artifact_option = (
103107
f'--artifact_storage_uri={artifact_uri}' if artifact_uri else ''
@@ -125,6 +129,7 @@ def to_cloud_run(
125129
session_service_uri: Optional[str] = None,
126130
artifact_service_uri: Optional[str] = None,
127131
memory_service_uri: Optional[str] = None,
132+
build_image: Optional[str] = BASE_BUILD_IMAGE,
128133
a2a: bool = False,
129134
):
130135
"""Deploys an agent to Google Cloud Run.
@@ -158,6 +163,7 @@ def to_cloud_run(
158163
session_service_uri: The URI of the session service.
159164
artifact_service_uri: The URI of the artifact service.
160165
memory_service_uri: The URI of the memory service.
166+
build_image: The image to use for building the Dockerfile.
161167
"""
162168
app_name = app_name or os.path.basename(agent_folder)
163169

@@ -206,6 +212,7 @@ def to_cloud_run(
206212
adk_version=adk_version,
207213
host_option=host_option,
208214
a2a_option=a2a_option,
215+
build_image=build_image,
209216
)
210217
dockerfile_path = os.path.join(temp_folder, 'Dockerfile')
211218
os.makedirs(temp_folder, exist_ok=True)
@@ -469,6 +476,7 @@ def to_gke(
469476
session_service_uri: Optional[str] = None,
470477
artifact_service_uri: Optional[str] = None,
471478
memory_service_uri: Optional[str] = None,
479+
build_image: Optional[str] = BASE_BUILD_IMAGE,
472480
a2a: bool = False,
473481
):
474482
"""Deploys an agent to Google Kubernetes Engine(GKE).
@@ -490,6 +498,7 @@ def to_gke(
490498
session_service_uri: The URI of the session service.
491499
artifact_service_uri: The URI of the artifact service.
492500
memory_service_uri: The URI of the memory service.
501+
build_image: The image to use for building the Dockerfile.
493502
"""
494503
click.secho(
495504
'\n🚀 Starting ADK Agent Deployment to GKE...', fg='cyan', bold=True
@@ -551,6 +560,7 @@ def to_gke(
551560
adk_version=adk_version,
552561
host_option=host_option,
553562
a2a_option='--a2a' if a2a else '',
563+
build_image=build_image,
554564
)
555565
dockerfile_path = os.path.join(temp_folder, 'Dockerfile')
556566
os.makedirs(temp_folder, exist_ok=True)

src/google/adk/cli/cli_tools_click.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
case_sensitive=False,
4545
)
4646

47+
BASE_BUILD_IMAGE = "python:3.11-slim"
48+
4749

4850
class HelpfulCommand(click.Command):
4951
"""Command that shows full help on error instead of just the error message.
@@ -968,6 +970,13 @@ def cli_api_server(
968970
help="Optional. Any additional origins to allow for CORS.",
969971
multiple=True,
970972
)
973+
@click.option(
974+
"--build_image",
975+
type=str,
976+
default=BASE_BUILD_IMAGE,
977+
show_default=True,
978+
help="Optional. The docker build version used in Cloud Run deployment. ",
979+
)
971980
# TODO: Add eval_storage_uri option back when evals are supported in Cloud Run.
972981
@adk_services_options()
973982
@deprecated_adk_services_options()
@@ -991,6 +1000,7 @@ def cli_deploy_cloud_run(
9911000
session_db_url: Optional[str] = None, # Deprecated
9921001
artifact_storage_uri: Optional[str] = None, # Deprecated
9931002
a2a: bool = False,
1003+
build_image: Optional[str] = BASE_BUILD_IMAGE,
9941004
):
9951005
"""Deploys an agent to Cloud Run.
9961006
@@ -1029,6 +1039,7 @@ def cli_deploy_cloud_run(
10291039
artifact_service_uri=artifact_service_uri,
10301040
memory_service_uri=memory_service_uri,
10311041
a2a=a2a,
1042+
build_image=build_image,
10321043
)
10331044
except Exception as e:
10341045
click.secho(f"Deploy failed: {e}", fg="red", err=True)
@@ -1281,6 +1292,13 @@ def cli_deploy_agent_engine(
12811292
" version in the dev environment)"
12821293
),
12831294
)
1295+
@click.option(
1296+
"--build_image",
1297+
type=str,
1298+
default=BASE_BUILD_IMAGE,
1299+
show_default=True,
1300+
help="Optional. The docker build version used in GKE deployment. ",
1301+
)
12841302
@adk_services_options()
12851303
@click.argument(
12861304
"agent",
@@ -1304,6 +1322,7 @@ def cli_deploy_gke(
13041322
session_service_uri: Optional[str] = None,
13051323
artifact_service_uri: Optional[str] = None,
13061324
memory_service_uri: Optional[str] = None,
1325+
build_image: Optional[str] = BASE_BUILD_IMAGE,
13071326
):
13081327
"""Deploys an agent to GKE.
13091328
@@ -1330,6 +1349,7 @@ def cli_deploy_gke(
13301349
session_service_uri=session_service_uri,
13311350
artifact_service_uri=artifact_service_uri,
13321351
memory_service_uri=memory_service_uri,
1352+
build_image=build_image,
13331353
)
13341354
except Exception as e:
13351355
click.secho(f"Deploy failed: {e}", fg="red", err=True)

src/google/adk/tools/google_api_tool/google_api_toolset.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ class GoogleApiToolset(BaseToolset):
3636
Usually one toolsets will contains tools only related to one Google API, e.g.
3737
Google Bigquery API toolset will contains tools only related to Google
3838
Bigquery API, like list dataset tool, list table tool etc.
39+
40+
Args:
41+
api_name: The name of the Google API (e.g., "calendar", "gmail").
42+
api_version: The version of the API (e.g., "v3", "v1").
43+
client_id: OAuth2 client ID for authentication.
44+
client_secret: OAuth2 client secret for authentication.
45+
tool_filter: Optional filter to include only specific tools or use a predicate function.
46+
service_account: Optional service account for authentication.
47+
tool_name_prefix: Optional prefix to add to all tool names in this toolset.
3948
"""
4049

4150
def __init__(
@@ -46,8 +55,9 @@ def __init__(
4655
client_secret: Optional[str] = None,
4756
tool_filter: Optional[Union[ToolPredicate, List[str]]] = None,
4857
service_account: Optional[ServiceAccount] = None,
58+
tool_name_prefix: Optional[str] = None,
4959
):
50-
super().__init__(tool_filter=tool_filter)
60+
super().__init__(tool_filter=tool_filter, tool_name_prefix=tool_name_prefix)
5161
self.api_name = api_name
5262
self.api_version = api_version
5363
self._client_id = client_id

0 commit comments

Comments
 (0)