Skip to content

Commit 16a4a86

Browse files
Merge branch 'main' into feat/firestore
2 parents 72cc9d2 + 9a19304 commit 16a4a86

18 files changed

Lines changed: 595 additions & 22 deletions

File tree

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "1.28.0"
2+
".": "1.29.0"
33
}

.github/release-please-config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
3-
"last-release-sha": "50209549206256abe5d1c5d84ab2b14dfdf80d66",
3+
"last-release-sha": "6b1600fbf53bcf634c5fe4793f02921bc0b75125",
44
"packages": {
55
".": {
66
"release-type": "python",

CHANGELOG.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,80 @@
11
# Changelog
22

3+
## [1.29.0](https://github.com/google/adk-python/compare/v1.28.0...v1.29.0) (2026-04-09)
4+
5+
6+
### Features
7+
8+
* Add auth scheme/credential support to MCP toolsets in Agent Registry ([7913a3b](https://github.com/google/adk-python/commit/7913a3b76432caf16953ea7b2a2cf4872baad417))
9+
* add ability to block shell metacharacters in BashTool ([23bd95b](https://github.com/google/adk-python/commit/23bd95bcf23367a8df3342ca4bb9d17f0b3b0d8f))
10+
* add configurable resource limits for subprocesses in BashTool ([1b05842](https://github.com/google/adk-python/commit/1b0584241f6418fd5fe9bd05fa666d03c310b8ae))
11+
* Add configurable view_prefix to BigQueryLoggerConfig ([37973da](https://github.com/google/adk-python/commit/37973daff47d3c67e928a240acd188d4e318f52b))
12+
* Add custom session id functionality to vertex ai session service ([e1913a6](https://github.com/google/adk-python/commit/e1913a6b411aec9e8774ca92ea39531b085c43f0))
13+
* Add Description column to SKILL.md and update terminology ([435f7c7](https://github.com/google/adk-python/commit/435f7c7a9fdf8b1214f4439c6d953b6426d90da1))
14+
* Add Easy GCP support to ADK CLI ([8850916](https://github.com/google/adk-python/commit/8850916e1908ace19a058102f0392eee08349d60))
15+
* Add regional endpoint support to `SecretManagerClient` ([19ac679](https://github.com/google/adk-python/commit/19ac679aeacc045ed78cb9fd48bb295440843288))
16+
* Add support for model endpoints in Agent Registry ([eb4674b](https://github.com/google/adk-python/commit/eb4674b49f017f3947506c55be4075b1ea0369d6))
17+
* **auth:** Add public api to register custom auth provider with credential manager ([a220910](https://github.com/google/adk-python/commit/a22091058dd2ea6e1e0655b5946ce6ed7e72d25e))
18+
* **auth:** Pass consent_nonce to Agent Frontend ([9fec503](https://github.com/google/adk-python/commit/9fec503061846b9903c18921f7848b358a041331))
19+
* **auth:** Support additional HTTP headers in MCP tools ([b3e9962](https://github.com/google/adk-python/commit/b3e99628ee1b87b61badf56e67f8ddee15e6fe54))
20+
* **bigquery:** Add ADK 1P Skills for ADK BQ Toolset ([4030c0d](https://github.com/google/adk-python/commit/4030c0d0167b348cf2e4c941c8610aa6ede28275))
21+
* **environment:** Add EnvironmentToolset for file I/O and command execution ([9082b9e](https://github.com/google/adk-python/commit/9082b9e38eeb3465c399b41633e6441e339c47c3))
22+
* **environment:** Add LocalEnvironment for executing commands and file I/O locally ([f973673](https://github.com/google/adk-python/commit/f97367381e820c75ad16d4ce7ee27c0f9929c81d))
23+
* Implement robust process group management and timeouts in BashTool ([f641b1a](https://github.com/google/adk-python/commit/f641b1a219b041659e6d429c47974bc9e5cfe1af))
24+
* **live:** Added in 1.28.1, support live for `gemini-3.1-flash-live-preview` model ([8082893](https://github.com/google/adk-python/commit/8082893619bb85d4ee0dc53fd2133d12b9434d07))
25+
* Option to use shallow-copy for session in InMemorySessionService ([16a1a18](https://github.com/google/adk-python/commit/16a1a185ab77a904fd01712779fa1bc6417dc628))
26+
* Propagate context to thread pools ([83393ab](https://github.com/google/adk-python/commit/83393ab839d5733568699195683408fccbd1cb6e))
27+
* refresh credentials if token is missing in the common code and samples ([1445ad5](https://github.com/google/adk-python/commit/1445ad5069841e446328e0856553f69a6699f0f4))
28+
* Remove use of raw_event field in vertex ai session service ([642d337](https://github.com/google/adk-python/commit/642d337a9069fae334192d045c9f85922cbcef53))
29+
* **skill:** Standardize skill tools and make script arguments flexible ([9e73ab8](https://github.com/google/adk-python/commit/9e73ab846672065f1fbe1c2642419e8a008efd43))
30+
* Support AgentRegistry association ([6754760](https://github.com/google/adk-python/commit/675476088b9f3c0a488ce48f652b7f3f7ea47230))
31+
* Support loading agents from Visual Builder with BigQuery-powered logging ([2074889](https://github.com/google/adk-python/commit/20748894cdaa5a95d0c4ccb0daf87a34496639dd))
32+
* Support propagating grounding metadata from AgentTool ([d689a04](https://github.com/google/adk-python/commit/d689a04f16846c2aa483dd45dcc65e2decdb419c))
33+
* Support short options and positional arguments in RunSkillScriptTool ([2b49163](https://github.com/google/adk-python/commit/2b49163b399135f0d96b73a99eb4ace764ce87db))
34+
* Use raw_event field in vertex ai session service for append and list events ([6ee0362](https://github.com/google/adk-python/commit/6ee036292e9eefabb032e8ebec3580a2243f3a96))
35+
* Use raw_event to store event data in vertex ai session service ([9da9dee](https://github.com/google/adk-python/commit/9da9dee140a3c8971d2dc267eab7d8d17a22a089))
36+
37+
38+
### Bug Fixes
39+
40+
* Add A2ATransport.http_json to the default supported transports list ([7dd9359](https://github.com/google/adk-python/commit/7dd9359fa1c419f82db84b844195e1b77d8070e7))
41+
* add httpx_client_factory support to SseConnectionParams ([815ebb4](https://github.com/google/adk-python/commit/815ebb441579724e5aa22830b2e6f7c22f94fde6))
42+
* **adk:** redact credentials in BigQuery analytics plugin ([a27ce47](https://github.com/google/adk-python/commit/a27ce4771ff271947a0d94762231da842095836e))
43+
* api client initialization logic to be mutually exclusive between ExpressMode and GCP projects ([4ffe8fb](https://github.com/google/adk-python/commit/4ffe8fb4a6befc9e9d0e838427b7bf4890df4ba3))
44+
* avoid load all agents in adk web server ([ede8a56](https://github.com/google/adk-python/commit/ede8a56a3cd18311ce82e761f0f3da6228fbc0d6))
45+
* Cache BaseToolset.get_tools() for calls within the same invocation ([92cad99](https://github.com/google/adk-python/commit/92cad99724d333760e4ebc6116951d78a9b1cb7a))
46+
* **cli:** fail Agent Engine deploy when config file path is invalid ([bbad9ec](https://github.com/google/adk-python/commit/bbad9ec64ce1617bc45148de97e6246752845b98))
47+
* Disable tool caching for skill toolset ([064f0d2](https://github.com/google/adk-python/commit/064f0d278e55e1e9fd6db1b6ccf3d1cb95cba47b))
48+
* Disallow args on /builder and Add warning about Web UI usage to CLI help ([dcee290](https://github.com/google/adk-python/commit/dcee2902729e178b41086c4039a3828917bbb9f3))
49+
* empty events_iterator assignment ([898c4e5](https://github.com/google/adk-python/commit/898c4e5f78b60c4c4732c7cd19ff2da9a64964a1))
50+
* **environment:** fix package references ([add8e86](https://github.com/google/adk-python/commit/add8e8664bd2ae9257c8b37a5e602d0c7aae7625))
51+
* Fix RemoteA2AAgent deepcopy errors ([6f29775](https://github.com/google/adk-python/commit/6f29775f4bf7172b1378b17856534f95b9d4eeb6))
52+
* Fixes for initializing RemoteA2aAgent - passing in preferred transport, protocol version, and auth headers ([0f3850f](https://github.com/google/adk-python/commit/0f3850f56c857dfb86c7ad8de372bcc7fe495968))
53+
* Generate IDs for FunctionCalls when processing streaming LLM responses ([fe41817](https://github.com/google/adk-python/commit/fe4181718d104843b974417c59203ed8a7b15255)), closes [#4609](https://github.com/google/adk-python/issues/4609)
54+
* Handle merging lists in deep_merge_dicts ([cdb3ff4](https://github.com/google/adk-python/commit/cdb3ff4e1f155c357f8cf720132d09bbc1446075))
55+
* In memory session service to evaluate dictionary keys and value into an isolated snapshot sequence before starting loop ([f75de59](https://github.com/google/adk-python/commit/f75de59362e07c0cce0ead723ceea3102081af4d))
56+
* include intermediate subagent final response events in evaluation intermediate data ([f8a6bd7](https://github.com/google/adk-python/commit/f8a6bd7fc0ca4b37cac4dc93c725c8973a1c9027))
57+
* **live:** Handle live session resumption and GoAway signal ([6b1600f](https://github.com/google/adk-python/commit/6b1600fbf53bcf634c5fe4793f02921bc0b75125)), closes [#4996](https://github.com/google/adk-python/issues/4996)
58+
* move BigQueryAgentAnalyticsPlugin import inside get_runner_async ([6fd0f85](https://github.com/google/adk-python/commit/6fd0f85191dea17b7c6b033473bd39764250265b))
59+
* Safer fix for UI widget merging in ADK ([0e71985](https://github.com/google/adk-python/commit/0e71985501c00682eff0f0c5328a3d429f2bdc68))
60+
* Small fixes for express mode ([3a374ce](https://github.com/google/adk-python/commit/3a374ce0aae73c138cd51d754220d0d7a64677b3))
61+
* sync callbacks with call_llm span ([b2daf83](https://github.com/google/adk-python/commit/b2daf83db406f8844f9db75abc7fee17362433b3))
62+
* **tools:** handle toolset errors gracefully in canonical_tools ([5df03f1](https://github.com/google/adk-python/commit/5df03f1f412e3ab55a5a6ceac892ba6b985a8036)), closes [#3341](https://github.com/google/adk-python/issues/3341)
63+
* truncate error_message in v0 schema to prevent VARCHAR overflow ([62daf4f](https://github.com/google/adk-python/commit/62daf4f61b14aee7bca9d8dec479bfd940bbb955)), closes [#4993](https://github.com/google/adk-python/issues/4993)
64+
* update toolbox-adk and toolbox server versions ([1486925](https://github.com/google/adk-python/commit/14869253d072e901d530fd3b7ee8ef67fbe5ddbc))
65+
66+
67+
### Code Refactoring
68+
69+
* Move SecretManagerClient to google.adk.integrations.secret_manager package ([1104523](https://github.com/google/adk-python/commit/110452375c6ccaa16e4ade7d7fe3438d185d4355))
70+
* Remove the session events dependency from A2aAgentExecutor ([aaa03ac](https://github.com/google/adk-python/commit/aaa03ac30841b2e12e3ddf4bb02fbcbf08ae13e8))
71+
72+
73+
### Documentation
74+
75+
* **adk:** clean up remote triggers README to remove internal references ([ccac461](https://github.com/google/adk-python/commit/ccac461b2ab6291ecd09577ca0553833eaff71b9))
76+
* Update the MCP Toolbox docsite with the new URL ([a60baca](https://github.com/google/adk-python/commit/a60baca3ddfe2541159b32d67b738a836d2395e7))
77+
378
## [1.28.0](https://github.com/google/adk-python/compare/v1.27.5...v1.28.0) (2026-03-26)
479

580

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Local Environment Skill Sample
2+
3+
This sample demonstrates how to use the `LocalEnvironment` with the `EnvironmentToolset` to allow an agent to manually discover and load skills from the environment, rather than using the pre-configured `SkillToolset`.
4+
5+
## Description
6+
7+
The agent is configured with the `EnvironmentToolset` and is initialized with a `LocalEnvironment` pointing to the agent's directory.
8+
Instead of having skills pre-loaded, the agent uses system instructions that guide it to search for skills in the `skills/` folder and load them by reading their `SKILL.md` files using the `ReadFile` tool.
9+
10+
This demonstrates a "manual skill loading" pattern where the agent can acquire new capabilities dynamically by reading instructions from the environment.
11+
12+
## Sample Usage
13+
14+
You can interact with the agent by providing prompts that require a specific skill (like weather).
15+
16+
### Example Prompt
17+
18+
> "Can you check the weather in Sunnyvale?"
19+
20+
### Expected Behavior
21+
22+
1. **Find Skill**: The agent uses the `Execute` tool to search for all available skills by running `find skills -name SKILL.md`.
23+
2. **Load Skill**: The agent identifies the relevant skill and uses the `ReadFile` tool to read its `SKILL.md` file.
24+
3. **Execute Skill**: The agent follows the instructions in the skill file (e.g., reading references or running scripts) to answer the user's request.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2026 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: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Copyright 2026 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+
import pathlib
15+
16+
from google.adk import Agent
17+
from google.adk.environment import LocalEnvironment
18+
from google.adk.tools.base_tool import BaseTool
19+
from google.adk.tools.environment import EnvironmentToolset
20+
from google.genai import types
21+
22+
23+
class GetTimezoneTool(BaseTool):
24+
"""A tool to get the timezone for a given location."""
25+
26+
def __init__(self):
27+
super().__init__(
28+
name="get_timezone",
29+
description="Returns the timezone for a given location.",
30+
)
31+
32+
def _get_declaration(self) -> types.FunctionDeclaration | None:
33+
return types.FunctionDeclaration(
34+
name=self.name,
35+
description=self.description,
36+
parameters_json_schema={
37+
"type": "object",
38+
"properties": {
39+
"location": {
40+
"type": "string",
41+
"description": "The location to get the timezone for.",
42+
},
43+
},
44+
"required": ["location"],
45+
},
46+
)
47+
48+
async def run_async(self, *, args: dict, tool_context) -> str:
49+
return f"The timezone for {args['location']} is UTC+00:00."
50+
51+
52+
def get_wind_speed(location: str) -> str:
53+
"""Returns the current wind speed for a given location."""
54+
return f"The wind speed in {location} is 10 mph."
55+
56+
57+
BASE_INSTRUCTION = (
58+
"You are a helpful AI assistant that can use the local environment to"
59+
" execute commands and file I/O."
60+
)
61+
62+
SKILL_USAGE_INSTRUCTION = """\
63+
[SKILLS ACCESS]
64+
You have access to specialized skills stored in the environment's `skills/` folder.
65+
Each skill is a folder containing a `SKILL.md` file with instructions.
66+
67+
[MANDATORY PROCEDURE]
68+
Before declaring that you cannot perform a task or answer a question (especially for domain-specific queries like weather), you MUST:
69+
1. Use the `Execute` tool to search for all available skills by running: `find skills -name SKILL.md`
70+
2. Review the list of found skills to see if any are relevant to the user's request.
71+
3. If a relevant skill is found, use the `ReadFile` tool to read its `SKILL.md` file.
72+
4. Follow the instructions in that file to complete the request.
73+
*CRITICAL NOTE ON PATHS:* All file and script paths mentioned inside a `SKILL.md` file (e.g., `references/...` or `scripts/...`) are RELATIVE to that specific skill's folder. You MUST resolve them by prepending the skill's folder path (e.g., if the skill is at `skills/weather-skill/`, you must read `skills/weather-skill/references/weather_info.md`).
74+
75+
Failure to check the `skills/` directory before stating you cannot help is unacceptable.\
76+
"""
77+
78+
79+
root_agent = Agent(
80+
model="gemini-2.5-pro",
81+
name="local_environment_skill_agent",
82+
description=(
83+
"An agent that uses local environment tools to load and use skills."
84+
),
85+
instruction=f"{BASE_INSTRUCTION}\n\n{SKILL_USAGE_INSTRUCTION}",
86+
tools=[
87+
EnvironmentToolset(
88+
environment=LocalEnvironment(
89+
working_dir=pathlib.Path(__file__).parent
90+
),
91+
),
92+
GetTimezoneTool(),
93+
get_wind_speed,
94+
],
95+
)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
name: weather-skill
3+
description: A skill that provides weather information based on reference data.
4+
metadata:
5+
adk_additional_tools:
6+
- get_wind_speed
7+
---
8+
9+
Step 1: Check 'references/weather_info.md' for the current weather.
10+
Step 2: If humidity is requested, use run 'scripts/get_humidity.py' with the `location` argument.
11+
Step 3: If wind speed is requested, use the `get_wind_speed` tool.
12+
Step 4: Provide the update to the user.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Weather Information
2+
3+
- **Location:** San Francisco, CA
4+
- **Condition:** Sunny ☀️
5+
- **Temperature:** 72°F (22°C)
6+
- **Forecast:** Clear skies all day.
7+
8+
- **Location:** Sunnyvale, CA
9+
- **Condition:** Sunny ☀️
10+
- **Temperature:** 75°F (24°C)
11+
- **Forecast:** Warm and sunny.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Copyright 2026 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 argparse
16+
17+
18+
def get_humidity(location: str) -> str:
19+
"""Fetch live humidity for a given location. (Simulated)"""
20+
print(f"Fetching live humidity for {location}...")
21+
return "45% (Simulated)"
22+
23+
24+
if __name__ == "__main__":
25+
parser = argparse.ArgumentParser()
26+
parser.add_argument("--location", type=str, default="Mountain View")
27+
args = parser.parse_args()
28+
29+
print(get_humidity(args.location))

src/google/adk/cli/adk_web_server.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -706,14 +706,10 @@ async def get_runner_async(self, app_name: str) -> Runner:
706706
if plugins_config and isinstance(plugins_config, dict):
707707
bq_analytics_config = plugins_config.get("bigquery_agent_analytics")
708708

709-
# Determine if the agent was loaded from YAML based on the agent loader info
710-
is_visual_builder = False
711-
detailed_agents = self.agent_loader.list_agents_detailed()
712-
for agent_info in detailed_agents:
713-
if agent_info.get("name") == app_name:
714-
if agent_info.get("language") == "yaml":
715-
is_visual_builder = True
716-
break
709+
# All YAML agents are treated as visual builder agents.
710+
is_visual_builder_agent = os.path.exists(
711+
os.path.join(self.agents_dir, app_name, "root_agent.yaml")
712+
)
717713

718714
if isinstance(agent_or_app, BaseAgent):
719715
plugins = extra_plugins_instances
@@ -746,7 +742,7 @@ async def get_runner_async(self, app_name: str) -> Runner:
746742
agentic_app = agent_or_app
747743

748744
# If the root agent was loaded from YAML, we treat it as being from Visual Builder
749-
if is_visual_builder:
745+
if is_visual_builder_agent:
750746
object.__setattr__(agentic_app, "_is_visual_builder_app", True)
751747

752748
runner = self._create_runner(agentic_app)

0 commit comments

Comments
 (0)