Skip to content

Commit cffeeaf

Browse files
authored
Merge branch 'main' into fix/handle-circular-refs
2 parents 0cdd4ab + 1206add commit cffeeaf

File tree

16 files changed

+1390
-59
lines changed

16 files changed

+1390
-59
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "1.25.1"
2+
".": "1.26.0"
33
}

.github/release-please-config.json

Lines changed: 46 additions & 11 deletions
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": "9f7d5b3f1476234e552b783415527cc4bac55b39",
3+
"last-release-sha": "8f5428150d18ed732b66379c0acb806a9121c3cb",
44
"packages": {
55
".": {
66
"release-type": "python",
@@ -10,16 +10,51 @@
1010
"skip-github-release": true,
1111
"changelog-path": "CHANGELOG.md",
1212
"changelog-sections": [
13-
{"type": "feat", "section": "Features"},
14-
{"type": "fix", "section": "Bug Fixes"},
15-
{"type": "perf", "section": "Performance Improvements"},
16-
{"type": "refactor", "section": "Code Refactoring"},
17-
{"type": "docs", "section": "Documentation"},
18-
{"type": "test", "section": "Tests", "hidden": true},
19-
{"type": "build", "section": "Build System", "hidden": true},
20-
{"type": "ci", "section": "CI/CD", "hidden": true},
21-
{"type": "style", "section": "Styles", "hidden": true},
22-
{"type": "chore", "section": "Miscellaneous Chores", "hidden": true}
13+
{
14+
"type": "feat",
15+
"section": "Features"
16+
},
17+
{
18+
"type": "fix",
19+
"section": "Bug Fixes"
20+
},
21+
{
22+
"type": "perf",
23+
"section": "Performance Improvements"
24+
},
25+
{
26+
"type": "refactor",
27+
"section": "Code Refactoring"
28+
},
29+
{
30+
"type": "docs",
31+
"section": "Documentation"
32+
},
33+
{
34+
"type": "test",
35+
"section": "Tests",
36+
"hidden": true
37+
},
38+
{
39+
"type": "build",
40+
"section": "Build System",
41+
"hidden": true
42+
},
43+
{
44+
"type": "ci",
45+
"section": "CI/CD",
46+
"hidden": true
47+
},
48+
{
49+
"type": "style",
50+
"section": "Styles",
51+
"hidden": true
52+
},
53+
{
54+
"type": "chore",
55+
"section": "Miscellaneous Chores",
56+
"hidden": true
57+
}
2358
]
2459
}
2560
}

.github/workflows/release-cherry-pick.yml

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Step 3 (optional): Cherry-picks a commit from main to the release/candidate branch.
22
# Use between step 1 and step 4 to include bug fixes in an in-progress release.
3+
# Note: Does NOT auto-trigger release-please to preserve manual changelog edits.
34
name: "Release: Cherry-pick"
45

56
on:
@@ -12,7 +13,6 @@ on:
1213

1314
permissions:
1415
contents: write
15-
actions: write
1616

1717
jobs:
1818
cherry-pick:
@@ -39,10 +39,5 @@ jobs:
3939
run: |
4040
git push origin release/candidate
4141
echo "Successfully cherry-picked commit to release/candidate"
42-
43-
- name: Trigger Release Please
44-
env:
45-
GH_TOKEN: ${{ github.token }}
46-
run: |
47-
gh workflow run release-please.yml --repo ${{ github.repository }} --ref release/candidate
48-
echo "Triggered Release Please workflow"
42+
echo "Note: Release Please is NOT auto-triggered to preserve manual changelog edits."
43+
echo "Run release-please.yml manually if you want to regenerate the changelog."

CHANGELOG.md

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

3+
## [1.26.0](https://github.com/google/adk-python/compare/v1.25.1...v1.26.0) (2026-02-26)
4+
5+
6+
### Features
7+
8+
* **[Core]**
9+
* Add intra-invocation compaction and token compaction pre-request ([485fcb8](https://github.com/google/adk-python/commit/485fcb84e3ca351f83416c012edcafcec479c1db))
10+
* Use `--memory_service_uri` in ADK CLI run command ([a7b5097](https://github.com/google/adk-python/commit/a7b509763c1732f0363e90952bb4c2672572d542))
11+
12+
* **[Models]**
13+
* Add `/chat/completions` integration to `ApigeeLlm` ([9c4c445](https://github.com/google/adk-python/commit/9c4c44536904f5cf3301a5abb910a5666344a8c5))
14+
* Add `/chat/completions` streaming support to Apigee LLM ([121d277](https://github.com/google/adk-python/commit/121d27741684685c564e484704ae949c5f0807b1))
15+
* Expand LiteLlm supported models and add registry tests ([d5332f4](https://github.com/google/adk-python/commit/d5332f44347f44d60360e14205a2342a0c990d66))
16+
17+
* **[Tools]**
18+
* Add `load_skill_from_dir()` method ([9f7d5b3](https://github.com/google/adk-python/commit/9f7d5b3f1476234e552b783415527cc4bac55b39))
19+
* Agent Skills spec compliance — validation, aliases, scripts, and auto-injection ([223d9a7](https://github.com/google/adk-python/commit/223d9a7ff52d8da702f1f436bd22e94ad78bd5da))
20+
* BigQuery ADK support for search catalog tool ([bef3f11](https://github.com/google/adk-python/commit/bef3f117b4842ce62760328304484cd26a1ec30a))
21+
* Make skill instruction optimizable and can adapt to user tasks ([21be6ad](https://github.com/google/adk-python/commit/21be6adcb86722a585b26f600c45c85e593b4ee0))
22+
* Pass trace context in MCP tool call's `_meta` field with OpenTelemetry propagator ([bcbfeba](https://github.com/google/adk-python/commit/bcbfeba953d46fca731b11542a00103cef374e57))
23+
24+
* **[Evals]**
25+
* Introduce User Personas to the ADK evaluation framework ([6a808c6](https://github.com/google/adk-python/commit/6a808c60b38ad7140ddeb222887c6accc63edce9))
26+
27+
* **[Services]**
28+
* Add generate/create modes for Vertex AI Memory Bank writes ([811e50a](https://github.com/google/adk-python/commit/811e50a0cbb181d502b9837711431ef78fca3f34))
29+
* Add support for memory consolidation via Vertex AI Memory Bank ([4a88804](https://github.com/google/adk-python/commit/4a88804ec7d17fb4031b238c362f27d240df0a13))
30+
31+
* **[A2A]**
32+
* Add interceptor framework to `A2aAgentExecutor` ([87fcd77](https://github.com/google/adk-python/commit/87fcd77caa9672f219c12e5a0e2ff65cbbaaf6f3))
33+
34+
* **[Auth]**
35+
* Add native support for `id_token` in OAuth2 credentials ([33f7d11](https://github.com/google/adk-python/commit/33f7d118b377b60f998c92944d2673679fddbc6e))
36+
* Support ID token exchange in `ServiceAccountCredentialExchanger` ([7be90db](https://github.com/google/adk-python/commit/7be90db24b41f1830e39ca3d7e15bf4dbfa5a304)), closes [#4458](https://github.com/google/adk-python/issues/4458)
37+
38+
* **[Integrations]**
39+
* Agent Registry in ADK ([abaa929](https://github.com/google/adk-python/commit/abaa92944c4cd43d206e2986d405d4ee07d45afe))
40+
* Add schema auto-upgrade, tool provenance, HITL tracing, and span hierarchy fix to BigQuery Agent Analytics plugin ([4260ef0](https://github.com/google/adk-python/commit/4260ef0c7c37ecdfea295fb0e1a933bb0df78bea))
41+
* Change default BigQuery table ID and update docstring ([7557a92](https://github.com/google/adk-python/commit/7557a929398ec2a1f946500d906cef5a4f86b5d1))
42+
* Update Agent Registry to create AgentCard from info in get agents endpoint ([c33d614](https://github.com/google/adk-python/commit/c33d614004a47d1a74951dd13628fd2300aeb9ef))
43+
44+
* **[Web]**
45+
* Enable dependency injection for agent loader in FastAPI app gen ([34da2d5](https://github.com/google/adk-python/commit/34da2d5b26e82f96f1951334fe974a0444843720))
46+
47+
48+
### Bug Fixes
49+
50+
* Add OpenAI strict JSON schema enforcement in LiteLLM ([2dbd1f2](https://github.com/google/adk-python/commit/2dbd1f25bdb1d88a6873d824b81b3dd5243332a4)), closes [#4573](https://github.com/google/adk-python/issues/4573)
51+
* Add push notification config store to agent_to_a2a ([4ca904f](https://github.com/google/adk-python/commit/4ca904f11113c4faa3e17bb4a9662dca1f936e2e)), closes [#4126](https://github.com/google/adk-python/issues/4126)
52+
* Add support for injecting a custom google.genai.Client into Gemini models ([48105b4](https://github.com/google/adk-python/commit/48105b49c5ab8e4719a66e7219f731b2cd293b00)), closes [#2560](https://github.com/google/adk-python/issues/2560)
53+
* Add support for injecting a custom google.genai.Client into Gemini models ([c615757](https://github.com/google/adk-python/commit/c615757ba12093ba4a2ba19bee3f498fef91584c)), closes [#2560](https://github.com/google/adk-python/issues/2560)
54+
* Check both `input_stream` parameter name and its annotation to decide whether it's a streaming tool that accept input stream ([d56cb41](https://github.com/google/adk-python/commit/d56cb4142c5040b6e7d13beb09123b8a59341384))
55+
* **deps:** Increase pydantic lower version to 2.7.0 ([dbd6420](https://github.com/google/adk-python/commit/dbd64207aebea8c5af19830a9a02d4c05d1d9469))
56+
* edit copybara and BUILD config for new adk/integrations folder (added with Agent Registry) ([37d52b4](https://github.com/google/adk-python/commit/37d52b4caf6738437e62fe804103efe4bde363a1))
57+
* Expand add_memory to accept MemoryEntry ([f27a9cf](https://github.com/google/adk-python/commit/f27a9cfb87caecb8d52967c50637ed5ad541cd07))
58+
* Fix pickling lock errors in McpSessionManager ([4e2d615](https://github.com/google/adk-python/commit/4e2d6159ae3552954aaae295fef3e09118502898))
59+
* fix typo in PlanReActPlanner instruction ([6d53d80](https://github.com/google/adk-python/commit/6d53d800d5f6dc5d4a3a75300e34d5a9b0f006f5))
60+
* handle UnicodeDecodeError when loading skills in ADK ([3fbc27f](https://github.com/google/adk-python/commit/3fbc27fa4ddb58b2b69ee1bea1e3a7b2514bd725))
61+
* Improve BigQuery Agent Analytics plugin reliability and code quality ([ea03487](https://github.com/google/adk-python/commit/ea034877ec15eef1be8f9a4be9fcd95446a3dc21))
62+
* Include list of skills in every message and remove list_skills tool from system instruction ([4285f85](https://github.com/google/adk-python/commit/4285f852d54670390b19302ed38306bccc0a7cee))
63+
* Invoke on_tool_error_callback for missing tools in live mode ([e6b601a](https://github.com/google/adk-python/commit/e6b601a2ab71b7e2df0240fd55550dca1eba8397))
64+
* Keep query params embedded in OpenAPI paths when using httpx ([ffbcc0a](https://github.com/google/adk-python/commit/ffbcc0a626deb24fe38eab402b3d6ace484115df)), closes [#4555](https://github.com/google/adk-python/issues/4555)
65+
* Only relay the LiveRequest after tools is invoked ([b53bc55](https://github.com/google/adk-python/commit/b53bc555cceaa11dc53b42c9ca1d650592fb4365))
66+
* Parallelize tool resolution in LlmAgent.canonical_tools() ([7478bda](https://github.com/google/adk-python/commit/7478bdaa9817b0285b4119e8c739d7520373f719))
67+
* race condition in table creation for `DatabaseSessionService` ([fbe9ecc](https://github.com/google/adk-python/commit/fbe9eccd05e628daa67059ba2e6a0d03966b240d))
68+
* Re-export DEFAULT_SKILL_SYSTEM_INSTRUCTION to skills and skill/prompt.py to avoid breaking current users ([40ec134](https://github.com/google/adk-python/commit/40ec1343c2708e1cf0d39cd8b8a96f3729f843de))
69+
* Refactor LiteLLM streaming response parsing for compatibility with LiteLLM 1.81+ ([e8019b1](https://github.com/google/adk-python/commit/e8019b1b1b0b43dcc5fa23075942b31db502ffdd)), closes [#4225](https://github.com/google/adk-python/issues/4225)
70+
* remove duplicate session GET when using API server, unbreak auto_session_create when using API server ([445dc18](https://github.com/google/adk-python/commit/445dc189e915ce5198e822ad7fadd6bb0880a95e))
71+
* Remove experimental decorators from user persona data models ([eccdf6d](https://github.com/google/adk-python/commit/eccdf6d01e70c37a1e5aa47c40d74469580365d2))
72+
* Replace the global DEFAULT_USER_PERSONA_REGISTRY with a function call to get_default_persona_registry ([2703613](https://github.com/google/adk-python/commit/2703613572a38bf4f9e25569be2ee678dc91b5b5))
73+
* **skill:** coloate default skill SI with skilltoolset ([fc1f1db](https://github.com/google/adk-python/commit/fc1f1db00562a79cd6c742cfd00f6267295c29a8))
74+
* Update agent_engine_sandbox_code_executor in ADK ([ee8d956](https://github.com/google/adk-python/commit/ee8d956413473d1bbbb025a470ad882c1487d8b8))
75+
* Update agent_engine_sandbox_code_executor in ADK ([dab80e4](https://github.com/google/adk-python/commit/dab80e4a8f3c5476f731335724bff5df3e6f3650))
76+
* Update sample skills agent to use weather-skill instead of weather_skill ([8f54281](https://github.com/google/adk-python/commit/8f5428150d18ed732b66379c0acb806a9121c3cb))
77+
* update Spanner query tools to async functions ([1dbcecc](https://github.com/google/adk-python/commit/1dbceccf36c28d693b0982b531a99877a3e75169))
78+
* use correct msg_out/msg_err keys for Agent Engine sandbox output ([b1e33a9](https://github.com/google/adk-python/commit/b1e33a90b4ba716d717e0488b84892b8a7f42aac))
79+
* Validate session before streaming instead of eagerly advancing the runner generator ([ab32f33](https://github.com/google/adk-python/commit/ab32f33e7418d452e65cf6f5b6cbfe1371600323))
80+
* **web:** allow session resume without new message ([30b2ed3](https://github.com/google/adk-python/commit/30b2ed3ef8ee6d3633743c0db00533683d3342d8))
81+
82+
83+
### Code Refactoring
84+
85+
* Extract reusable function for building agent transfer instructions ([e1e0d63](https://github.com/google/adk-python/commit/e1e0d6361675e7b9a2c9b2523e3a72e2e5e7ce05))
86+
* Extract reusable private methods ([976a238](https://github.com/google/adk-python/commit/976a238544330528b4f9f4bea6c4e75ec13b33e1))
87+
* Extract reusable private methods ([42eeaef](https://github.com/google/adk-python/commit/42eeaef2b34c860f126c79c552435458614255ad))
88+
* Extract reusable private methods ([706f9fe](https://github.com/google/adk-python/commit/706f9fe74db0197e19790ca542d372ce46d0ae87))
89+
90+
91+
### Documentation
92+
93+
* add `thinking_config` in `generate_content_config` in example agent ([c6b1c74](https://github.com/google/adk-python/commit/c6b1c74321faf62cc52d2518eb9ea0dcef050cde))
94+
395
## [1.25.1](https://github.com/google/adk-python/compare/v1.25.0...v1.25.1) (2026-02-18)
496

597
### Bug Fixes

contributing/samples/skills_agent/agent.py

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

1919
from google.adk import Agent
20+
from google.adk.code_executors.unsafe_local_code_executor import UnsafeLocalCodeExecutor
2021
from google.adk.skills import load_skill_from_dir
2122
from google.adk.skills import models
2223
from google.adk.tools.skill_toolset import SkillToolset
@@ -44,7 +45,12 @@
4445
pathlib.Path(__file__).parent / "skills" / "weather-skill"
4546
)
4647

47-
my_skill_toolset = SkillToolset(skills=[greeting_skill, weather_skill])
48+
# WARNING: UnsafeLocalCodeExecutor has security concerns and should NOT
49+
# be used in production environments.
50+
my_skill_toolset = SkillToolset(
51+
skills=[greeting_skill, weather_skill],
52+
code_executor=UnsafeLocalCodeExecutor(),
53+
)
4854

4955
root_agent = Agent(
5056
model="gemini-2.5-flash",

contributing/samples/skills_agent/skills/weather-skill/SKILL.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ description: A skill that provides weather information based on reference data.
44
---
55

66
Step 1: Check 'references/weather_info.md' for the current weather.
7-
Step 2: Provide the weather update to the user.
7+
Step 2: If humidity is requested, use run 'scripts/get_humidity.py' with the `location` argument.
8+
Step 3: Provide the update to the user.
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: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,46 +1668,39 @@ async def run_agent(req: RunAgentRequest) -> list[Event]:
16681668
async def run_agent_sse(req: RunAgentRequest) -> StreamingResponse:
16691669
stream_mode = StreamingMode.SSE if req.streaming else StreamingMode.NONE
16701670
runner = await self.get_runner_async(req.app_name)
1671-
agen = runner.run_async(
1672-
user_id=req.user_id,
1673-
session_id=req.session_id,
1674-
new_message=req.new_message,
1675-
state_delta=req.state_delta,
1676-
run_config=RunConfig(streaming_mode=stream_mode),
1677-
invocation_id=req.invocation_id,
1678-
)
16791671

1680-
# Eagerly advance the generator to trigger session validation
1681-
# before the streaming response is created. This lets us return
1682-
# a proper HTTP 404 for missing sessions without a redundant
1683-
# get_session call — the Runner's single _get_or_create_session
1684-
# call is the only one that runs.
1685-
first_event = None
1686-
first_error = None
1687-
try:
1688-
first_event = await anext(agen)
1689-
except SessionNotFoundError as e:
1690-
await agen.aclose()
1691-
raise HTTPException(status_code=404, detail=str(e)) from e
1692-
except StopAsyncIteration:
1693-
await agen.aclose()
1694-
except Exception as e:
1695-
first_error = e
1672+
# Validate session existence before starting the stream.
1673+
# We check directly here instead of eagerly advancing the
1674+
# runner's async generator with anext(), because splitting
1675+
# generator consumption across two asyncio Tasks (request
1676+
# handler vs StreamingResponse) breaks OpenTelemetry context
1677+
# detachment.
1678+
if not runner.auto_create_session:
1679+
session = await self.session_service.get_session(
1680+
app_name=req.app_name,
1681+
user_id=req.user_id,
1682+
session_id=req.session_id,
1683+
)
1684+
if not session:
1685+
raise HTTPException(
1686+
status_code=404,
1687+
detail=f"Session not found: {req.session_id}",
1688+
)
16961689

16971690
# Convert the events to properly formatted SSE
16981691
async def event_generator():
1699-
async with Aclosing(agen):
1692+
async with Aclosing(
1693+
runner.run_async(
1694+
user_id=req.user_id,
1695+
session_id=req.session_id,
1696+
new_message=req.new_message,
1697+
state_delta=req.state_delta,
1698+
run_config=RunConfig(streaming_mode=stream_mode),
1699+
invocation_id=req.invocation_id,
1700+
)
1701+
) as agen:
17001702
try:
1701-
if first_error:
1702-
raise first_error
1703-
1704-
async def all_events():
1705-
if first_event is not None:
1706-
yield first_event
1707-
async for event in agen:
1708-
yield event
1709-
1710-
async for event in all_events():
1703+
async for event in agen:
17111704
# ADK Web renders artifacts from `actions.artifactDelta`
17121705
# during part processing *and* during action processing
17131706
# 1) the original event with `artifactDelta` cleared (content)

0 commit comments

Comments
 (0)