Skip to content

Commit 0012809

Browse files
authored
Merge branch 'main' into redact-db-url-password-in-errors
2 parents c229b01 + 455853b commit 0012809

30 files changed

Lines changed: 6576 additions & 682 deletions

.pre-commit-config.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ repos:
6464
# This script documents and matches the very patterns it forbids, so
6565
# it must not scan itself or other dev-only tooling.
6666
exclude: ^scripts/
67+
- id: update-constraints
68+
name: update-constraints
69+
entry: ./scripts/update_constraints.sh
70+
language: system
71+
files: ^(pyproject\.toml|constraints-.*\.txt)$
72+
pass_filenames: false
6773
- repo: https://github.com/executablebooks/mdformat
6874
rev: 0.7.22
6975
hooks:

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ pip install google-adk
4949

5050
**Requirements:** Python 3.10+.
5151

52+
For transitive dependency protection, we recommend to install with our companion
53+
constraints files (for python 3.10 to 3.14).
54+
55+
Choose the constraints file matching your Python version:
56+
57+
```bash
58+
# For example, for Python 3.10
59+
curl -o constraints-3.10.txt https://github.com/google/adk-python/blob/main/constraints-3.10.txt
60+
pip install google-adk -c constraints-3.10.txt
61+
rm constraints-3.10.txt
62+
```
63+
5264
To install optional integrations, you can use the following command:
5365

5466
```bash

contributing/samples/multi_agent/task_sub_agent/tests/10_burgers.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
},
4343
{
4444
"author": "order_collector",
45+
"branch": "order_collector@fc-1",
4546
"content": {
4647
"parts": [
4748
{
@@ -99,6 +100,7 @@
99100
},
100101
{
101102
"author": "order_collector",
103+
"branch": "order_collector@fc-1",
102104
"content": {
103105
"parts": [
104106
{
@@ -133,6 +135,7 @@
133135
},
134136
{
135137
"author": "order_collector",
138+
"branch": "order_collector@fc-1",
136139
"content": {
137140
"parts": [
138141
{
@@ -156,6 +159,7 @@
156159
},
157160
{
158161
"author": "order_collector",
162+
"branch": "order_collector@fc-1",
159163
"content": {
160164
"parts": [
161165
{
@@ -199,6 +203,7 @@
199203
"skipSummarization": true
200204
},
201205
"author": "order_collector",
206+
"branch": "order_collector@fc-1",
202207
"content": {
203208
"parts": [
204209
{

contributing/samples/multi_agent/task_sub_agent/tests/3_burgers.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
},
4343
{
4444
"author": "order_collector",
45+
"branch": "order_collector@fc-1",
4546
"content": {
4647
"parts": [
4748
{
@@ -76,6 +77,7 @@
7677
},
7778
{
7879
"author": "order_collector",
80+
"branch": "order_collector@fc-1",
7981
"content": {
8082
"parts": [
8183
{
@@ -106,6 +108,7 @@
106108
},
107109
{
108110
"author": "order_collector",
111+
"branch": "order_collector@fc-1",
109112
"content": {
110113
"parts": [
111114
{
@@ -189,6 +192,7 @@
189192
},
190193
{
191194
"author": "payment_collector",
195+
"branch": "payment_collector@fc-3",
192196
"content": {
193197
"parts": [
194198
{
@@ -223,6 +227,7 @@
223227
},
224228
{
225229
"author": "payment_collector",
230+
"branch": "payment_collector@fc-3",
226231
"content": {
227232
"parts": [
228233
{
@@ -257,6 +262,7 @@
257262
},
258263
{
259264
"author": "payment_collector",
265+
"branch": "payment_collector@fc-3",
260266
"content": {
261267
"parts": [
262268
{
@@ -283,6 +289,7 @@
283289
},
284290
{
285291
"author": "payment_collector",
292+
"branch": "payment_collector@fc-3",
286293
"content": {
287294
"parts": [
288295
{

contributing/samples/multi_agent/task_sub_agent/tests/credit_card.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
},
4343
{
4444
"author": "order_collector",
45+
"branch": "order_collector@fc-1",
4546
"content": {
4647
"parts": [
4748
{
@@ -76,6 +77,7 @@
7677
},
7778
{
7879
"author": "order_collector",
80+
"branch": "order_collector@fc-1",
7981
"content": {
8082
"parts": [
8183
{

contributing/samples/multi_agent/task_sub_agent/tests/order_food.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
},
4343
{
4444
"author": "order_collector",
45+
"branch": "order_collector@fc-1",
4546
"content": {
4647
"parts": [
4748
{
@@ -76,6 +77,7 @@
7677
},
7778
{
7879
"author": "order_collector",
80+
"branch": "order_collector@fc-1",
7981
"content": {
8082
"parts": [
8183
{
@@ -110,6 +112,7 @@
110112
},
111113
{
112114
"author": "order_collector",
115+
"branch": "order_collector@fc-1",
113116
"content": {
114117
"parts": [
115118
{
@@ -144,6 +147,7 @@
144147
},
145148
{
146149
"author": "order_collector",
150+
"branch": "order_collector@fc-1",
147151
"content": {
148152
"parts": [
149153
{
@@ -178,6 +182,7 @@
178182
},
179183
{
180184
"author": "order_collector",
185+
"branch": "order_collector@fc-1",
181186
"content": {
182187
"parts": [
183188
{

scripts/update_constraints.sh

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
#!/bin/bash
2+
# Copyright 2026 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# Manage constraints.txt: check if up-to-date or automatically update it.
17+
#
18+
# Usage:
19+
# ./scripts/update_constraints.sh # Updates constraints.txt in-place if out of date
20+
# ./scripts/update_constraints.sh --check # Check only, exits with 1 if out of date (for CI)
21+
22+
set -e
23+
24+
# Parse arguments
25+
CHECK_ONLY=false
26+
for arg in "$@"; do
27+
case $arg in
28+
--check)
29+
CHECK_ONLY=true
30+
shift
31+
;;
32+
esac
33+
done
34+
35+
# Ensure uv is in PATH
36+
export PATH="$HOME/.local/bin:$PATH"
37+
38+
cleanup() {
39+
rm -f constraints-*.tmp
40+
}
41+
trap cleanup EXIT
42+
43+
PYTHON_VERSIONS=("3.10" "3.11" "3.12" "3.13" "3.14")
44+
EXIT_CODE=0
45+
46+
# Calculate 4 days ago date
47+
if [ "$CHECK_ONLY" = false ]; then
48+
if date -v-4d +%Y-%m-%d >/dev/null 2>&1; then
49+
EXCLUDE_NEWER_DATE=$(date -v-4d +%Y-%m-%d)
50+
else
51+
EXCLUDE_NEWER_DATE=$(date -d "4 days ago" +%Y-%m-%d)
52+
fi
53+
fi
54+
55+
for ver in "${PYTHON_VERSIONS[@]}"; do
56+
TARGET_FILE="constraints-${ver}.txt"
57+
echo "Processing $TARGET_FILE..."
58+
59+
if [ ! -f "$TARGET_FILE" ]; then
60+
if [ "$CHECK_ONLY" = true ]; then
61+
echo "$TARGET_FILE is missing!"
62+
EXIT_CODE=1
63+
continue
64+
fi
65+
fi
66+
67+
# Default date to what we calculated (for update mode)
68+
date_to_use="$EXCLUDE_NEWER_DATE"
69+
70+
if [ -f "$TARGET_FILE" ]; then
71+
if [ "$CHECK_ONLY" = true ]; then
72+
# In check mode, extract the date used when it was generated
73+
date_to_use=$(grep -h "# uv pip compile" "$TARGET_FILE" | grep -oE -- '--exclude-newer [0-9]{4}-[0-9]{2}-[0-9]{2}' | cut -d' ' -f2 || true)
74+
fi
75+
fi
76+
77+
# Construct the command from scratch
78+
GENERATION_CMD="uv pip compile pyproject.toml --all-extras --python-version $ver"
79+
if [ -n "$date_to_use" ]; then
80+
GENERATION_CMD="$GENERATION_CMD --exclude-newer $date_to_use"
81+
fi
82+
GENERATION_CMD="$GENERATION_CMD --index-url https://pypi.org/simple -o $TARGET_FILE"
83+
84+
echo "Found generation command: $GENERATION_CMD"
85+
86+
STABLE_FILE="constraints-${ver}.txt.stable.tmp"
87+
NEW_FILE="constraints-${ver}.txt.new.tmp"
88+
89+
# Copy the existing constraints to STABLE_FILE if it exists and is not empty
90+
if [ -s "$TARGET_FILE" ]; then
91+
cp "$TARGET_FILE" "$STABLE_FILE"
92+
else
93+
touch "$STABLE_FILE"
94+
fi
95+
96+
# Modify the GENERATION_CMD to output to NEW_FILE.
97+
RUN_CMD=$(echo "$GENERATION_CMD" | sed -E "s/-o [^ ]+/-o $NEW_FILE/")
98+
RUN_CMD=$(echo "$RUN_CMD" | sed -E "s/--output-file [^ ]+/--output-file $NEW_FILE/")
99+
RUN_CMD=$(echo "$RUN_CMD" | sed -E "s/--output-file=[^ ]+/--output-file=$NEW_FILE/")
100+
101+
# Execute the command, also adding STABLE_FILE as a constraint to stabilize resolution.
102+
echo "Running: $RUN_CMD --constraint $STABLE_FILE"
103+
if ! eval "$RUN_CMD --constraint $STABLE_FILE"; then
104+
if [ "$CHECK_ONLY" = true ]; then
105+
echo "❌ Resolution failed with stable constraints for $TARGET_FILE."
106+
echo " This usually happens when a new dependency requirement in pyproject.toml conflicts with existing pinned versions."
107+
echo " To fix this, run the update script locally to resolve conflicts and update constraints:"
108+
echo " $ ./scripts/update_constraints.sh"
109+
rm -f "$STABLE_FILE" "$NEW_FILE"
110+
EXIT_CODE=1
111+
continue
112+
else
113+
echo "⚠️ Resolution failed with stable constraints. Retrying without constraints to allow upgrades..."
114+
echo "Running: $RUN_CMD"
115+
if ! eval "$RUN_CMD"; then
116+
echo "❌ Resolution failed even without constraints."
117+
rm -f "$STABLE_FILE" "$NEW_FILE"
118+
EXIT_CODE=1
119+
continue
120+
fi
121+
fi
122+
fi
123+
124+
# Reconstruct NEW_FILE to have the clean GENERATION_CMD in its header
125+
CLEAN_FILE="constraints-${ver}.txt.clean.tmp"
126+
{
127+
echo "# This file was autogenerated by uv via the following command:"
128+
echo "# $GENERATION_CMD"
129+
tail -n +3 "$NEW_FILE"
130+
} > "$CLEAN_FILE"
131+
mv "$CLEAN_FILE" "$NEW_FILE"
132+
133+
# Compare
134+
if diff -u "$TARGET_FILE" "$NEW_FILE"; then
135+
echo "$TARGET_FILE is up-to-date."
136+
rm -f "$STABLE_FILE" "$NEW_FILE"
137+
else
138+
if [ "$CHECK_ONLY" = true ]; then
139+
echo "$TARGET_FILE is OUT OF DATE!"
140+
echo " Please run the update script locally to update it and commit the changes:"
141+
echo " $ ./scripts/update_constraints.sh"
142+
rm -f "$STABLE_FILE" "$NEW_FILE"
143+
EXIT_CODE=1
144+
else
145+
echo "🔄 $TARGET_FILE was OUT OF DATE. Updating it automatically..."
146+
cp "$NEW_FILE" "$TARGET_FILE"
147+
echo "$TARGET_FILE has been updated locally."
148+
rm -f "$STABLE_FILE" "$NEW_FILE"
149+
EXIT_CODE=1
150+
fi
151+
fi
152+
done
153+
154+
exit $EXIT_CODE

src/google/adk/errors/session_not_found_error.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ class SessionNotFoundError(ValueError):
2121
Inherits from ValueError (for backward compatibility).
2222
"""
2323

24-
def __init__(self, message="Session not found."):
24+
def __init__(self, message: str = "Session not found.") -> None:
2525
super().__init__(message)

src/google/adk/integrations/agent_registry/agent_registry.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,11 @@ def _use_client_cert_effective() -> bool:
648648
def _should_use_mtls_endpoint(client_cert_source: Any | None = None) -> bool:
649649
"""Returns whether the mTLS endpoint should be used."""
650650
try:
651-
return bool(mtls.should_use_mtls_endpoint())
651+
return bool(
652+
mtls.should_use_mtls_endpoint(
653+
client_cert_available=client_cert_source is not None
654+
)
655+
)
652656
except (ImportError, AttributeError):
653657
pass
654658
use_mtls_endpoint_str = os.getenv(

src/google/adk/integrations/firestore/firestore_session_service.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from typing import Optional
3030

3131
from ...errors.already_exists_error import AlreadyExistsError
32+
from ...errors.session_not_found_error import SessionNotFoundError
3233
from ...events.event import Event
3334
from ...platform import uuid as platform_uuid
3435
from ...sessions import _session_util
@@ -504,7 +505,7 @@ async def _append_txn(transaction: firestore.AsyncTransaction) -> int:
504505
# 1. Reads
505506
session_snap = await session_ref.get(transaction=transaction)
506507
if not session_snap.exists:
507-
raise ValueError(f"Session {session.id} not found.")
508+
raise SessionNotFoundError(f"Session {session.id} not found.")
508509

509510
session_doc = session_snap.to_dict() or {}
510511
if session_doc.get("status") == "DELETING":

0 commit comments

Comments
 (0)