Skip to content

Commit 6090957

Browse files
authored
Merge branch 'main' into feature/ollama-llm
2 parents 95bb377 + 5f806ed commit 6090957

File tree

15 files changed

+377
-97
lines changed

15 files changed

+377
-97
lines changed

.github/workflows/check-file-contents.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ jobs:
3030

3131
- name: Check for logger pattern in all changed Python files
3232
run: |
33-
git fetch origin ${GITHUB_BASE_REF}
34-
CHANGED_FILES=$(git diff --diff-filter=ACMR --name-only origin/${GITHUB_BASE_REF}...HEAD | grep -E '\.py$' || true)
33+
git fetch origin ${{ github.base_ref }}
34+
CHANGED_FILES=$(git diff --diff-filter=ACMR --name-only origin/${{ github.base_ref }}...HEAD | grep -E '\.py$' || true)
3535
if [ -n "$CHANGED_FILES" ]; then
3636
echo "Changed Python files to check:"
3737
echo "$CHANGED_FILES"
@@ -61,8 +61,8 @@ jobs:
6161
6262
- name: Check for import pattern in certain changed Python files
6363
run: |
64-
git fetch origin ${GITHUB_BASE_REF}
65-
CHANGED_FILES=$(git diff --diff-filter=ACMR --name-only origin/${GITHUB_BASE_REF}...HEAD | grep -E '\.py$' | grep -v -E '__init__.py$|version.py$|tests/.*|contributing/samples/' || true)
64+
git fetch origin ${{ github.base_ref }}
65+
CHANGED_FILES=$(git diff --diff-filter=ACMR --name-only origin/${{ github.base_ref }}...HEAD | grep -E '\.py$' | grep -v -E '__init__.py$|version.py$|tests/.*|contributing/samples/' || true)
6666
if [ -n "$CHANGED_FILES" ]; then
6767
echo "Changed Python files to check:"
6868
echo "$CHANGED_FILES"
@@ -88,8 +88,8 @@ jobs:
8888
8989
- name: Check for import from cli package in certain changed Python files
9090
run: |
91-
git fetch origin ${GITHUB_BASE_REF}
92-
CHANGED_FILES=$(git diff --diff-filter=ACMR --name-only origin/${GITHUB_BASE_REF}...HEAD | grep -E '\.py$' | grep -v -E 'cli/.*|src/google/adk/tools/apihub_tool/apihub_toolset.py|tests/.*|contributing/samples/' || true)
91+
git fetch origin ${{ github.base_ref }}
92+
CHANGED_FILES=$(git diff --diff-filter=ACMR --name-only origin/${{ github.base_ref }}...HEAD | grep -E '\.py$' | grep -v -E 'cli/.*|src/google/adk/tools/apihub_tool/apihub_toolset.py|tests/.*|contributing/samples/' || true)
9393
if [ -n "$CHANGED_FILES" ]; then
9494
echo "Changed Python files to check:"
9595
echo "$CHANGED_FILES"
@@ -110,4 +110,4 @@ jobs:
110110
fi
111111
else
112112
echo "✅ No relevant Python files found."
113-
fi
113+
fi

.github/workflows/isort.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ jobs:
4242
- name: Run isort on changed files
4343
id: run_isort
4444
run: |
45-
git fetch origin ${GITHUB_BASE_REF}
46-
CHANGED_FILES=$(git diff --diff-filter=ACMR --name-only origin/${GITHUB_BASE_REF}...HEAD | grep -E '\.py$' || true)
45+
git fetch origin ${{ github.base_ref }}
46+
CHANGED_FILES=$(git diff --diff-filter=ACMR --name-only origin/${{ github.base_ref }}...HEAD | grep -E '\.py$' || true)
4747
if [ -n "$CHANGED_FILES" ]; then
4848
echo "Changed Python files:"
4949
echo "$CHANGED_FILES"

.github/workflows/pyink.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ jobs:
4242
- name: Run pyink on changed files
4343
id: run_pyink
4444
run: |
45-
git fetch origin ${GITHUB_BASE_REF}
46-
CHANGED_FILES=$(git diff --diff-filter=ACMR --name-only origin/${GITHUB_BASE_REF}...HEAD | grep -E '\.py$' || true)
45+
git fetch origin ${{ github.base_ref }}
46+
CHANGED_FILES=$(git diff --diff-filter=ACMR --name-only origin/${{ github.base_ref }}...HEAD | grep -E '\.py$' || true)
4747
if [ -n "$CHANGED_FILES" ]; then
4848
echo "Changed Python files:"
4949
echo "$CHANGED_FILES"

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,8 @@ jobs:
3030
3131
- name: Cherry-pick commit
3232
run: |
33-
echo "Cherry-picking ${INPUTS_COMMIT_SHA} to release/candidate"
34-
git cherry-pick ${INPUTS_COMMIT_SHA}
35-
env:
36-
INPUTS_COMMIT_SHA: ${{ inputs.commit_sha }}
33+
echo "Cherry-picking ${{ inputs.commit_sha }} to release/candidate"
34+
git cherry-pick ${{ inputs.commit_sha }}
3735
3836
- name: Push changes
3937
run: |

.github/workflows/release-finalize.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,9 @@ jobs:
6868
- name: Rename release/candidate to release/v{version}
6969
if: steps.check.outputs.is_release_pr == 'true'
7070
run: |
71-
VERSION="v${STEPS_VERSION_OUTPUTS_VERSION}"
71+
VERSION="v${{ steps.version.outputs.version }}"
7272
git push origin "release/candidate:refs/heads/release/$VERSION" ":release/candidate"
7373
echo "Renamed release/candidate to release/$VERSION"
74-
env:
75-
STEPS_VERSION_OUTPUTS_VERSION: ${{ steps.version.outputs.version }}
7674
7775
- name: Update PR label to tagged
7876
if: steps.check.outputs.is_release_pr == 'true'

.github/workflows/release-publish.yml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ jobs:
1515
steps:
1616
- name: Validate branch
1717
run: |
18-
if [[ ! "${GITHUB_REF_NAME}" =~ ^release/v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
18+
if [[ ! "${{ github.ref_name }}" =~ ^release/v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
1919
echo "Error: Must run from a release/v* branch (e.g., release/v0.3.0)"
2020
exit 1
2121
fi
2222
2323
- name: Extract version
2424
id: version
2525
run: |
26-
VERSION="${GITHUB_REF_NAME}"
26+
VERSION="${{ github.ref_name }}"
2727
VERSION="${VERSION#release/v}"
2828
echo "version=$VERSION" >> $GITHUB_OUTPUT
2929
echo "Publishing version: $VERSION"
@@ -51,10 +51,9 @@ jobs:
5151
- name: Create merge-back PR
5252
env:
5353
GH_TOKEN: ${{ secrets.RELEASE_PAT }}
54-
STEPS_VERSION_OUTPUTS_VERSION: ${{ steps.version.outputs.version }}
5554
run: |
5655
gh pr create \
5756
--base main \
58-
--head "${GITHUB_REF_NAME}" \
59-
--title "chore: merge release v${STEPS_VERSION_OUTPUTS_VERSION} to main" \
60-
--body "Syncs version bump and CHANGELOG from release v${STEPS_VERSION_OUTPUTS_VERSION} to main."
57+
--head "${{ github.ref_name }}" \
58+
--title "chore: merge release v${{ steps.version.outputs.version }} to main" \
59+
--body "Syncs version bump and CHANGELOG from release v${{ steps.version.outputs.version }} to main."

contributing/samples/bigtable/agent.py

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,17 @@
1616

1717
from google.adk.agents.llm_agent import LlmAgent
1818
from google.adk.auth.auth_credential import AuthCredentialTypes
19+
from google.adk.tools.bigtable import query_tool as bigtable_query_tool
1920
from google.adk.tools.bigtable.bigtable_credentials import BigtableCredentialsConfig
2021
from google.adk.tools.bigtable.bigtable_toolset import BigtableToolset
2122
from google.adk.tools.bigtable.settings import BigtableToolSettings
23+
from google.adk.tools.google_tool import GoogleTool
2224
import google.auth
25+
from google.cloud.bigtable.data.execute_query.metadata import SqlType
2326

24-
# Define an appropriate credential type
25-
CREDENTIALS_TYPE = AuthCredentialTypes.OAUTH2
26-
27+
# Define an appropriate credential type.
28+
# None for Application Default Credentials
29+
CREDENTIALS_TYPE = None
2730

2831
# Define Bigtable tool config with read capability set to allowed.
2932
tool_settings = BigtableToolSettings()
@@ -59,6 +62,53 @@
5962
credentials_config=credentials_config, bigtable_tool_settings=tool_settings
6063
)
6164

65+
_BIGTABLE_PROJECT_ID = "google.com:cloud-bigtable-dev"
66+
_BIGTABLE_INSTANCE_ID = "annenguyen-bus-instance"
67+
68+
69+
def search_hotels_by_location(
70+
location_name: str,
71+
credentials: google.auth.credentials.Credentials,
72+
settings: BigtableToolSettings,
73+
tool_context: google.adk.tools.tool_context.ToolContext,
74+
):
75+
"""Search hotels by location name.
76+
77+
This function takes a location name and returns a list of hotels
78+
in that area.
79+
80+
Args:
81+
location_name (str): The geographical location (e.g., city or town) for the
82+
hotel search.
83+
Example: { "location_name": "Basel" }
84+
85+
Returns:
86+
The hotels name, price tier.
87+
"""
88+
89+
sql_template = """
90+
SELECT
91+
TO_INT64(cf['id']) as id,
92+
CAST(cf['name'] AS STRING) AS name,
93+
CAST(cf['location'] AS STRING) AS location,
94+
CAST(cf['price_tier'] AS STRING) AS price_tier,
95+
CAST(cf['checkin_date'] AS STRING) AS checkin_date,
96+
CAST(cf['checkout_date'] AS STRING) AS checkout_date
97+
FROM hotels
98+
WHERE LOWER(CAST(cf['location'] AS STRING)) LIKE LOWER(CONCAT('%', @location_name, '%'))
99+
"""
100+
return bigtable_query_tool.execute_sql(
101+
project_id=_BIGTABLE_PROJECT_ID,
102+
instance_id=_BIGTABLE_INSTANCE_ID,
103+
query=sql_template,
104+
credentials=credentials,
105+
settings=settings,
106+
tool_context=tool_context,
107+
parameters={"location": location_name},
108+
parameter_types={"location": SqlType.String()},
109+
)
110+
111+
62112
# The variable name `root_agent` determines what your root agent is for the
63113
# debug CLI
64114
root_agent = LlmAgent(
@@ -72,5 +122,13 @@
72122
You are a data agent with access to several Bigtable tools.
73123
Make use of those tools to answer the user's questions.
74124
""",
75-
tools=[bigtable_toolset],
125+
tools=[
126+
bigtable_toolset,
127+
# Or, uncomment to use customized Bigtable tools.
128+
# GoogleTool(
129+
# func=search_hotels_by_location,
130+
# credentials_config=credentials_config,
131+
# tool_settings=tool_settings,
132+
# ),
133+
],
76134
)

src/google/adk/agents/invocation_context.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -396,23 +396,20 @@ def should_pause_invocation(self, event: Event) -> bool:
396396
return False
397397

398398
# TODO: Move this method from invocation_context to a dedicated module.
399-
# TODO: Converge this method with find_matching_function_call in llm_flows.
400399
def _find_matching_function_call(
401400
self, function_response_event: Event
402401
) -> Optional[Event]:
403402
"""Finds the function call event in the current invocation that matches the function response id."""
403+
from ..flows.llm_flows.functions import find_event_by_function_call_id
404+
404405
function_responses = function_response_event.get_function_responses()
405406
if not function_responses:
406407
return None
407-
function_call_id = function_responses[0].id
408-
409-
events = self._get_events(current_invocation=True)
410-
# The last event is function_response_event, so we search backwards from the
411-
# one before it.
412-
for event in reversed(events[:-1]):
413-
if any(fc.id == function_call_id for fc in event.get_function_calls()):
414-
return event
415-
return None
408+
409+
# Search backwards from the event before the current response event.
410+
return find_event_by_function_call_id(
411+
self._get_events(current_invocation=True)[:-1], function_responses[0].id
412+
)
416413

417414

418415
def new_invocation_context_id() -> str:

src/google/adk/flows/llm_flows/functions.py

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
from google.genai import types
3838

3939
from ...agents.active_streaming_tool import ActiveStreamingTool
40-
from ...agents.invocation_context import InvocationContext
4140
from ...agents.live_request_queue import LiveRequestQueue
4241
from ...auth.auth_tool import AuthConfig
4342
from ...auth.auth_tool import AuthToolArguments
@@ -52,6 +51,7 @@
5251
from ...utils.context_utils import Aclosing
5352

5453
if TYPE_CHECKING:
54+
from ...agents.invocation_context import InvocationContext
5555
from ...agents.llm_agent import LlmAgent
5656

5757
AF_FUNCTION_CALL_ID_PREFIX = 'adk-'
@@ -1157,6 +1157,18 @@ def merge_parallel_function_response_events(
11571157
return merged_event
11581158

11591159

1160+
def find_event_by_function_call_id(
1161+
events: list[Event],
1162+
function_call_id: str,
1163+
) -> Optional[Event]:
1164+
"""Finds the function call event that matches the function call id."""
1165+
for event in reversed(events):
1166+
for function_call in event.get_function_calls():
1167+
if function_call.id == function_call_id:
1168+
return event
1169+
return None
1170+
1171+
11601172
def find_matching_function_call(
11611173
events: list[Event],
11621174
) -> Optional[Event]:
@@ -1165,25 +1177,8 @@ def find_matching_function_call(
11651177
return None
11661178

11671179
last_event = events[-1]
1168-
if (
1169-
last_event.content
1170-
and last_event.content.parts
1171-
and any(part.function_response for part in last_event.content.parts)
1172-
):
1180+
function_responses = last_event.get_function_responses()
1181+
if not function_responses:
1182+
return None
11731183

1174-
function_call_id = next(
1175-
part.function_response.id
1176-
for part in last_event.content.parts
1177-
if part.function_response
1178-
)
1179-
for i in range(len(events) - 2, -1, -1):
1180-
event = events[i]
1181-
# looking for the system long-running request euc function call
1182-
function_calls = event.get_function_calls()
1183-
if not function_calls:
1184-
continue
1185-
1186-
for function_call in function_calls:
1187-
if function_call.id == function_call_id:
1188-
return event
1189-
return None
1184+
return find_event_by_function_call_id(events[:-1], function_responses[0].id)

0 commit comments

Comments
 (0)