Skip to content

Commit 4a3febf

Browse files
authored
Merge branch 'main' into spelling
2 parents e361ae6 + d4b2a8b commit 4a3febf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+5823
-4268
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,12 @@ We welcome contributions from the community! Whether it's bug reports, feature r
155155
- [General contribution guideline and flow](https://google.github.io/adk-docs/contributing-guide/).
156156
- Then if you want to contribute code, please read [Code Contributing Guidelines](./CONTRIBUTING.md) to get started.
157157

158+
## Community Repo
159+
160+
We have [adk-python-community repo](https://github.com/google/adk-python-community)that is home to a growing ecosystem of community-contributed tools, third-party
161+
service integrations, and deployment scripts that extend the core capabilities
162+
of the ADK.
163+
158164
## Vibe Coding
159165

160166
If you are to develop agent via vibe coding the [llms.txt](./llms.txt) and the [llms-full.txt](./llms-full.txt) can be used as context to LLM. While the former one is a summarized one and the later one has the full information in case your LLM has big enough context window.

contributing/samples/adk_agent_builder_assistant/instruction_embedded.template

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,19 @@ tools:
202202
```
203203
**DO NOT create Python files like `tools/google_search_tool.py` for built-in tools!**
204204

205+
- **🚫 Tool Hallucination Ban**
206+
- Use only the built-in tool names enumerated in the **ADK Built-in Tools**
207+
list above; never invent additional built-in labels.
208+
- If you cannot confirm that a tool already exists in this project or in the
209+
built-in list, ask the user for confirmation instead of guessing or fabricating
210+
the implementation.
211+
- Do not generate custom helper tools whose only purpose is transferring control
212+
to another agent; ADK injects the official `transfer_to_agent` tool
213+
automatically when sub-agents are configured. Avoid creating look-alikes such
214+
as `transfer_to_agent_tool`.
215+
- `tool_code` is reserved by some runtimes for code execution. Do not reuse that
216+
name for ADK tools or dotted paths.
217+
205218
**Custom Tools** (require Python implementation):
206219
- **Naming**: Use dotted path: `{{project_folder_name}}.tools.{{module_name}}.{{function_name}}`
207220
- **Require Python file**: Must create actual Python file in `tools/` directory

contributing/samples/adk_triaging_agent/agent.py

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,33 @@
4141
"a2a": "seanzhou1023",
4242
}
4343

44+
LABEL_GUIDELINES = """
45+
Label rubric and disambiguation rules:
46+
- "documentation": Tutorials, README content, reference docs, or samples.
47+
- "services": Session and memory services, persistence layers, or storage
48+
integrations.
49+
- "web": ADK web UI, FastAPI server, dashboards, or browser-based flows.
50+
- "question": Usage questions without a reproducible problem.
51+
- "tools": Built-in tools (e.g., SQL utils, code execution) or tool APIs.
52+
- "mcp": Model Context Protocol features. Apply both "mcp" and "tools".
53+
- "eval": Evaluation framework, test harnesses, scoring, or datasets.
54+
- "live": Streaming, bidi, audio, or Gemini Live configuration.
55+
- "models": Non-Gemini model adapters (LiteLLM, Ollama, OpenAI, etc.).
56+
- "tracing": Telemetry, observability, structured logs, or spans.
57+
- "core": Core ADK runtime (Agent definitions, Runner, planners,
58+
thinking config, CLI commands, GlobalInstructionPlugin, CPU usage, or
59+
general orchestration). Default to "core" when the topic is about ADK
60+
behavior and no other label is a better fit.
61+
- "agent engine": Vertex AI Agent Engine deployment or sandbox topics
62+
only (e.g., `.agent_engine_config.json`, `ae_ignore`, Agent Engine
63+
sandbox, `agent_engine_id`). If the issue does not explicitly mention
64+
Agent Engine concepts, do not use this label—choose "core" instead.
65+
- "a2a": Agent-to-agent workflows, coordination logic, or A2A protocol.
66+
67+
When unsure between labels, prefer the most specific match. If a label
68+
cannot be assigned confidently, do not call the labeling tool.
69+
"""
70+
4471
APPROVAL_INSTRUCTION = (
4572
"Do not ask for user approval for labeling! If you can't find appropriate"
4673
" labels for the issue, do not label it."
@@ -171,18 +198,20 @@ def change_issue_type(issue_number: int, issue_type: str) -> dict[str, Any]:
171198
You are a triaging bot for the GitHub {REPO} repo with the owner {OWNER}. You will help get issues, and recommend a label.
172199
IMPORTANT: {APPROVAL_INSTRUCTION}
173200
201+
{LABEL_GUIDELINES}
202+
174203
Here are the rules for labeling:
175204
- If the user is asking about documentation-related questions, label it with "documentation".
176-
- If it's about session, memory services, label it with "services"
177-
- If it's about UI/web, label it with "web"
178-
- If the user is asking about a question, label it with "question"
179-
- If it's related to tools, label it with "tools"
205+
- If it's about session, memory services, label it with "services".
206+
- If it's about UI/web, label it with "web".
207+
- If the user is asking about a question, label it with "question".
208+
- If it's related to tools, label it with "tools".
180209
- If it's about agent evaluation, then label it with "eval".
181210
- If it's about streaming/live, label it with "live".
182-
- If it's about model support(non-Gemini, like Litellm, Ollama, OpenAI models), label it with "models".
211+
- If it's about model support (non-Gemini, like Litellm, Ollama, OpenAI models), label it with "models".
183212
- If it's about tracing, label it with "tracing".
184-
- If it's agent orchestration, agent definition, label it with "core".
185-
- If it's about agent engine, label it with "agent engine".
213+
- If it's agent orchestration, agent definition, Runner behavior, planners, or performance, label it with "core".
214+
- Use "agent engine" only when the issue clearly references Vertex AI Agent Engine deployment artifacts (for example `.agent_engine_config.json`, `ae_ignore`, `agent_engine_id`, or Agent Engine sandbox errors).
186215
- If it's about Model Context Protocol (e.g. MCP tool, MCP toolset, MCP session management etc.), label it with both "mcp" and "tools".
187216
- If it's about A2A integrations or workflows, label it with "a2a".
188217
- If you can't find an appropriate labels for the issue, follow the previous instruction that starts with "IMPORTANT:".
@@ -194,6 +223,14 @@ def change_issue_type(issue_number: int, issue_type: str) -> dict[str, Any]:
194223
- If the issue is a feature request, change the issue type to "Feature".
195224
- Otherwise, **do not change the issue type**.
196225
226+
Response quality requirements:
227+
- Summarize the issue in your own words without leaving template
228+
placeholders (never output text like "[fill in later]").
229+
- Justify the chosen label with a short explanation referencing the issue
230+
details.
231+
- Mention the assigned owner when a label maps to one.
232+
- If no label is applied, clearly state why.
233+
197234
Present the followings in an easy to read format highlighting issue number and your label.
198235
- the issue summary in a few sentence
199236
- your label recommendation and justification
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# LiteLLM with Fallback Models
2+
3+
This agent is built for resilience using LiteLLM's built-in fallback mechanism. It automatically switches models to guard against common disruptions like token limit errors and connection failures, while ensuring full conversational context is preserved across all model changes.
4+
5+
To run this example, ensure your .env file includes the following variables:
6+
```
7+
GOOGLE_API_KEY=
8+
OPENAI_API_KEY=
9+
ANTHROPIC_API_KEY=
10+
```
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
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+
from . import agent
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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+
import random
16+
17+
from google.adk import Agent
18+
from google.adk.models.lite_llm import LiteLlm
19+
from google.adk.tools.tool_context import ToolContext
20+
from google.genai import types
21+
22+
23+
def roll_die(sides: int, tool_context: ToolContext) -> int:
24+
"""Roll a die and return the rolled result.
25+
26+
Args:
27+
sides: The integer number of sides the die has.
28+
tool_context: The tool context to use for the die roll.
29+
30+
Returns:
31+
An integer of the result of rolling the die.
32+
The result is also stored in the tool context for future use.
33+
"""
34+
result = random.randint(1, sides)
35+
if 'rolls' not in tool_context.state:
36+
tool_context.state['rolls'] = []
37+
38+
tool_context.state['rolls'] = tool_context.state['rolls'] + [result]
39+
return result
40+
41+
42+
async def before_model_callback(callback_context, llm_request):
43+
print('@before_model_callback')
44+
print(f'Beginning model choice: {llm_request.model}')
45+
callback_context.state['beginning_model_choice'] = llm_request.model
46+
return None
47+
48+
49+
async def after_model_callback(callback_context, llm_response):
50+
print('@after_model_callback')
51+
print(f'Final model choice: {llm_response.model_version}')
52+
callback_context.state['final_model_choice'] = llm_response.model_version
53+
return None
54+
55+
56+
root_agent = Agent(
57+
model=LiteLlm(
58+
model='gemini/gemini-2.5-pro',
59+
fallbacks=[
60+
'anthropic/claude-sonnet-4-5-20250929',
61+
'openai/gpt-4o',
62+
],
63+
),
64+
name='resilient_agent',
65+
description=(
66+
'hello world agent that can roll a dice of given number of sides.'
67+
),
68+
instruction="""
69+
You roll dice and answer questions about the outcome of the dice rolls.
70+
You can roll dice of different sizes.
71+
It is ok to discuss previous dice roles, and comment on the dice rolls.
72+
When you are asked to roll a die, you must call the roll_die tool with the number of sides. Be sure to pass in an integer. Do not pass in a string.
73+
You should never roll a die on your own.
74+
""",
75+
tools=[
76+
roll_die,
77+
],
78+
generate_content_config=types.GenerateContentConfig(
79+
safety_settings=[
80+
types.SafetySetting( # avoid false alarm about rolling dice.
81+
category=types.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
82+
threshold=types.HarmBlockThreshold.OFF,
83+
),
84+
]
85+
),
86+
before_model_callback=before_model_callback,
87+
after_model_callback=after_model_callback,
88+
)

contributing/samples/mcp_sse_agent/agent.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,27 @@
1616
import os
1717

1818
from google.adk.agents.llm_agent import LlmAgent
19+
from google.adk.agents.mcp_instruction_provider import McpInstructionProvider
1920
from google.adk.tools.mcp_tool.mcp_session_manager import SseConnectionParams
2021
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset
2122

2223
_allowed_path = os.path.dirname(os.path.abspath(__file__))
2324

25+
connection_params = SseConnectionParams(
26+
url='http://localhost:3000/sse',
27+
headers={'Accept': 'text/event-stream'},
28+
)
29+
2430
root_agent = LlmAgent(
2531
model='gemini-2.0-flash',
2632
name='enterprise_assistant',
27-
instruction=f"""\
28-
Help user accessing their file systems.
29-
30-
Allowed directory: {_allowed_path}
31-
""",
33+
instruction=McpInstructionProvider(
34+
connection_params=connection_params,
35+
prompt_name='file_system_prompt',
36+
),
3237
tools=[
3338
MCPToolset(
34-
connection_params=SseConnectionParams(
35-
url='http://localhost:3000/sse',
36-
headers={'Accept': 'text/event-stream'},
37-
),
39+
connection_params=connection_params,
3840
# don't want agent to do write operation
3941
# you can also do below
4042
# tool_filter=lambda tool, ctx=None: tool.name

contributing/samples/mcp_sse_agent/filesystem_server.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ def get_cwd() -> str:
4545
return str(Path.cwd())
4646

4747

48+
# Add a prompt for accessing file systems
49+
@mcp.prompt(name="file_system_prompt")
50+
def file_system_prompt() -> str:
51+
return f"""\
52+
Help the user access their file systems."""
53+
54+
4855
# Graceful shutdown handler
4956
async def shutdown(signal, loop):
5057
"""Cleanup tasks tied to the service's shutdown."""

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,12 @@ classifiers = [ # List of https://pypi.org/classifiers/
2626
dependencies = [
2727
# go/keep-sorted start
2828
"PyYAML>=6.0.2, <7.0.0", # For APIHubToolset.
29-
"absolufy-imports>=0.3.1, <1.0.0", # For Agent Engine deployment.
3029
"anyio>=4.9.0, <5.0.0;python_version>='3.10'", # For MCP Session Manager
3130
"authlib>=1.5.1, <2.0.0", # For RestAPI Tool
3231
"click>=8.1.8, <9.0.0", # For CLI tools
3332
"fastapi>=0.115.0, <1.119.0", # FastAPI framework
3433
"google-api-python-client>=2.157.0, <3.0.0", # Google API client discovery
35-
"google-cloud-aiplatform[agent_engines]>=1.121.0, <2.0.0", # For VertexAI integrations, e.g. example store.
34+
"google-cloud-aiplatform[agent_engines] @ git+https://github.com/googleapis/python-aiplatform.git@bf1851e59cb34e63b509a2a610e72691e1c4ca28", # For VertexAI integrations, e.g. example store.
3635
"google-cloud-bigtable>=2.32.0", # For Bigtable database
3736
"google-cloud-discoveryengine>=0.13.12, <0.14.0", # For Discovery Engine Search Tool
3837
"google-cloud-secret-manager>=2.22.0, <3.0.0", # Fetching secrets in RestAPI Tool

src/google/adk/agents/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import logging
16+
import sys
17+
1518
from .base_agent import BaseAgent
1619
from .invocation_context import InvocationContext
1720
from .live_request_queue import LiveRequest
@@ -35,3 +38,16 @@
3538
'LiveRequestQueue',
3639
'RunConfig',
3740
]
41+
42+
if sys.version_info < (3, 10):
43+
logger = logging.getLogger('google_adk.' + __name__)
44+
logger.warning(
45+
'MCP requires Python 3.10 or above. Please upgrade your Python'
46+
' version in order to use it.'
47+
)
48+
else:
49+
from .mcp_instruction_provider import McpInstructionProvider
50+
51+
__all__.extend([
52+
'McpInstructionProvider',
53+
])

0 commit comments

Comments
 (0)