Compare commits

..

35 Commits

Author SHA1 Message Date
Xiang (Sean) Zhou 832a633351 chore: Enhance a2a part converters
a. fix binary data conversion
b. support thoughts, code execution result, executable codes conversion

PiperOrigin-RevId: 775827259
2025-06-25 13:58:49 -07:00
Xuan Yang 738d1a8b84 chore: create an agent to check issue format and content for bugs and feature requests
This agent will pose a comment to ask for more information according to the template if necessary.

PiperOrigin-RevId: 775742256
2025-06-25 10:20:45 -07:00
Hangfei Lin 5306ddad4d chore: Release 1.5.0
PiperOrigin-RevId: 775742049
2025-06-25 10:19:20 -07:00
Xiang (Sean) Zhou a623467299 chore: Enhance a2a context id parsing and construction logic
PiperOrigin-RevId: 775718282
2025-06-25 09:19:16 -07:00
Xiang (Sean) Zhou f54b9b6ad1 chore: Add unit tests for contents.py
PiperOrigin-RevId: 775713101
2025-06-25 09:06:01 -07:00
Google Team Member 6729edd08e refactor: Rename the Google API based bigquery sample agent
This change renames the sample agent based on the Google API based tools to reflect the larger purpose and avoid confusion with the built-in BigQuery tools. In addition, it also renames the root agent in the BigQuery sample agent to "bigquery_agent"

PiperOrigin-RevId: 775655226
2025-06-25 06:05:32 -07:00
Xiang (Sean) Zhou 917a8a19f7 chore: Adapt oauth calendar agent to use authenticated tool
PiperOrigin-RevId: 775433950
2025-06-24 16:46:20 -07:00
Aditya Mulik ef3c745d65 fix: typo fix in sample agent instruction
Merge https://github.com/google/adk-python/pull/1623

fix: minor typo fix in the agent instruction
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/1623 from adityamulik:minor_typo_fix 12ea09ae397b5c5e2a9ada48017cd1ca14add72e
PiperOrigin-RevId: 775433411
2025-06-24 16:44:34 -07:00
Shangjie Chen 88a4402d14 chore: Do not send api request when session does not have events
PiperOrigin-RevId: 775423356
2025-06-24 16:15:23 -07:00
Dave Bunten 09f1269bf7 ci(tests): leverage official uv action for install
Merge https://github.com/google/adk-python/pull/1547

This PR replaces the `curl`-based installation of `uv` to instead use the [official GitHub Action from Astral](https://github.com/astral-sh/setup-uv).

Closes #1545

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/1547 from d33bs:use-uv-action 05ab7a138cbb5babee30ea81e83f26064e041529
PiperOrigin-RevId: 775402484
2025-06-24 15:18:18 -07:00
Google Team Member 9e473e0abd fix: Include current turn context when include_contents='none'
The intended behavior for include_contents='none' is to:
- Exclude conversation history from previous turns
- Still include current turn context (user input, tool calls/responses within current turn)

https://google.github.io/adk-docs/agents/llm-agents/#managing-context-include_contents

This resolves https://github.com/google/adk-python/issues/1124

PiperOrigin-RevId: 775400036
2025-06-24 15:11:33 -07:00
Xiang (Sean) Zhou acbdca0d84 fix: Make raw_auth_credential and exchanged_auth_credential optional given their default value is None
PiperOrigin-RevId: 775397286
2025-06-24 15:03:54 -07:00
Google Team Member ed7a21e189 chore: Update google-genai package and related deps to latest
PiperOrigin-RevId: 775394737
2025-06-24 14:57:56 -07:00
Liang Wu a1e1441115 fix: update contributing links
Merge https://github.com/google/adk-python/pull/1528

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/1528 from google:doc ec8325e126aba7257de73ab26d8d3a30064859b4
PiperOrigin-RevId: 775383121
2025-06-24 14:27:25 -07:00
Genquan Duan f33e0903b2 feat: Add ADK examples for litellm with add_function_to_prompt
Add examples for for https://github.com/google/adk-python/issues/1273

PiperOrigin-RevId: 775352677
2025-06-24 13:08:44 -07:00
Shangjie Chen abc89d2c81 feat: Add implementation of VertexAiMemoryBankService and support in FastAPI endpoint
PiperOrigin-RevId: 775327151
2025-06-24 11:57:03 -07:00
Google Team Member 00cc8cd643 feat: Add Vertex Express mode compatibility for VertexAiSessionService
PiperOrigin-RevId: 775317848
2025-06-24 11:33:37 -07:00
Joseph Pagadora 9597a446fd feat: Add rouge_score library to ADK eval dependencies, and implement RougeEvaluator that is computes ROUGE-1 for "response_match_score" metric
PiperOrigin-RevId: 774949712
2025-06-23 15:31:03 -07:00
Joseph Pagadora fa025d7559 feat: Add a new option eval_storage_uri in adk web & adk eval to specify GCS bucket to store eval data
PiperOrigin-RevId: 774947795
2025-06-23 15:24:57 -07:00
Xiang (Sean) Zhou 120cbabeb2 refactor: Rename long util function name in runner.py and move it to functions.py
PiperOrigin-RevId: 774880990
2025-06-23 12:24:10 -07:00
Xiang (Sean) Zhou 29cd183aa1 chore: Add credential service backed by session state
PiperOrigin-RevId: 774878336
2025-06-23 12:16:03 -07:00
avidelatm bd67e8480f fix: make LiteLLM streaming truly asynchronous
Merge https://github.com/google/adk-python/pull/1451

## Description
Fixes https://github.com/google/adk-python/issues/1306 by using `async for` with `await self.llm_client.acompletion()` instead of synchronous `for` loop.

## Changes
- Updated test mocks to properly handle async streaming by creating an async generator
- Ensured proper parameter handling to avoid duplicate stream parameter

## Testing Plan
- All unit tests now pass with the async streaming implementation
- Verified with `pytest tests/unittests/models/test_litellm.py` that all streaming tests pass
- Manually tested with a sample agent using LiteLLM to confirm streaming works properly

# Test Evidence:
https://youtu.be/hSp3otI79DM

Let me know if you need anything else from me for this PR

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/1451 from avidelatm:fix/litellm-async-streaming d35b9dc90b2fd6fad44c3869de0fda2514e50055
PiperOrigin-RevId: 774835130
2025-06-23 10:30:12 -07:00
Keisuke Oohashi ea69c9093a feat: add usage span attributes to telemetry (#356)
Merge https://github.com/google/adk-python/pull/1079

Fixes part of #356

Add usage attributes to span.
Note: Since the handling of GenAI event bodies in OpenTelemetry has not yet been determined, I have temporarily added only attributes related to usage.
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/1079 from soundTricker:feature/356-support-more-opentelemetry-semantics 99a9d0352b4bca165baa645440e39ce7199f072b
PiperOrigin-RevId: 774834279
2025-06-23 10:28:14 -07:00
Shangjie Chen f033e405c1 chore: Clarify the behavior of Event.invocation_id
PiperOrigin-RevId: 774827874
2025-06-23 10:12:16 -07:00
bck-ob-gh 3b1d9a8a3e fix: Use starred tuple unpacking on GCS artifact blob names
Merges https://github.com/google/adk-python/pull/1471

Fixes google#1436

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/1471 from bck-ob-gh:main 4c4f2b66ab1e6fde8b1a9d2b914dcb24040db144
PiperOrigin-RevId: 774809270
2025-06-23 09:24:31 -07:00
Xiang (Sean) Zhou 7c670f638b chore: Send user message to the agent that returned a corresponding function call if user message is a function response
PiperOrigin-RevId: 773895971
2025-06-20 17:15:29 -07:00
Xiang (Sean) Zhou fb13963ded chore: Add request converter to convert a2a request to ADK request
PiperOrigin-RevId: 773894462
2025-06-20 17:09:05 -07:00
Shangjie Chen 2fd8feb65d chore: Support allow_origins in cloud_run deployment
Also reorganize the fast_api_common_options. This resolves https://github.com/google/adk-python/issues/1444.

PiperOrigin-RevId: 773890111
2025-06-20 16:54:08 -07:00
Shangjie Chen 8677d5c8dc chore: bump version number to 1.4.2
PiperOrigin-RevId: 773867075
2025-06-20 15:41:50 -07:00
Shangjie Chen 4d72d31b13 fix: Add type checking to handle different response type of genai API client
Fixes https://github.com/google/adk-python/issues/1514

PiperOrigin-RevId: 773838035
2025-06-20 14:12:55 -07:00
Xiang (Sean) Zhou 742478fdb7 chore: Add event converters to convert adk event to a2a event (WIP)
PiperOrigin-RevId: 773795427
2025-06-20 12:14:12 -07:00
Xiang (Sean) Zhou ffcba70686 chore: skip mcp and a2a tests for python 3.9
PiperOrigin-RevId: 773785385
2025-06-20 11:46:31 -07:00
Google Team Member 2f716ada7f fix: Allow more credentials types for BigQuery tools
This change accepts the `google.auth.credentials.Credentials` type for `BigQueryCredentialsConfig`, so any subclass of that, including `google.oauth2.credentials.Credentials` would work to integrate with BigQuery service. This opens up a whole range of possibilities, such as using service account credentials to deploy an agent using these tools.

PiperOrigin-RevId: 773190440
2025-06-18 22:02:09 -07:00
Shangjie Chen 17beb32880 chore: Bump version number and update changelog for 1.4.1 release
PiperOrigin-RevId: 773148349
2025-06-18 19:08:43 -07:00
Xiang (Sean) Zhou 7f8dc8927a chore: fix the mcp_sse_agent
PiperOrigin-RevId: 773140021
2025-06-18 18:32:06 -07:00
76 changed files with 5801 additions and 353 deletions
+3
View File
@@ -31,5 +31,8 @@ If applicable, add screenshots to help explain your problem.
- Python version(python -V):
- ADK version(pip show google-adk):
**Model Information:**
For example, which model is being used.
**Additional context**
Add any other context about the problem here.
+2 -2
View File
@@ -36,8 +36,8 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Install the latest version of uv
uses: astral-sh/setup-uv@v6
- name: Install dependencies
run: |
+1
View File
@@ -82,6 +82,7 @@ log/
.env.development.local
.env.test.local
.env.production.local
uv.lock
# Google Cloud specific
.gcloudignore
+79
View File
@@ -1,5 +1,84 @@
# Changelog
## [1.5.0](https://github.com/google/adk-python/compare/v1.4.2...v1.5.0) (2025-06-25)
### Features
* Add a new option `eval_storage_uri` in adk web & adk eval to specify GCS bucket to store eval data ([fa025d7](https://github.com/google/adk-python/commit/fa025d755978e1506fa0da1fecc49775bebc1045))
* Add ADK examples for litellm with add_function_to_prompt ([f33e090](https://github.com/google/adk-python/commit/f33e0903b21b752168db3006dd034d7d43f7e84d))
* Add implementation of VertexAiMemoryBankService and support in FastAPI endpoint ([abc89d2](https://github.com/google/adk-python/commit/abc89d2c811ba00805f81b27a3a07d56bdf55a0b))
* Add rouge_score library to ADK eval dependencies, and implement RougeEvaluator that is computes ROUGE-1 for "response_match_score" metric ([9597a44](https://github.com/google/adk-python/commit/9597a446fdec63ad9e4c2692d6966b14f80ff8e2))
* Add usage span attributes to telemetry ([#356](https://github.com/google/adk-python/issues/356)) ([ea69c90](https://github.com/google/adk-python/commit/ea69c9093a16489afdf72657136c96f61c69cafd))
* Add Vertex Express mode compatibility for VertexAiSessionService ([00cc8cd](https://github.com/google/adk-python/commit/00cc8cd6433fc45ecfc2dbaa04dbbc1a81213b4d))
### Bug Fixes
* Include current turn context when include_contents='none' ([9e473e0](https://github.com/google/adk-python/commit/9e473e0abdded24e710fd857782356c15d04b515))
* Make LiteLLM streaming truly asynchronous ([bd67e84](https://github.com/google/adk-python/commit/bd67e8480f6e8b4b0f8c22b94f15a8cda1336339))
* Make raw_auth_credential and exchanged_auth_credential optional given their default value is None ([acbdca0](https://github.com/google/adk-python/commit/acbdca0d8400e292ba5525931175e0d6feab15f1))
* Minor typo fix in the agent instruction ([ef3c745](https://github.com/google/adk-python/commit/ef3c745d655538ebd1ed735671be615f842341a8))
* Typo fix in sample agent instruction ([ef3c745](https://github.com/google/adk-python/commit/ef3c745d655538ebd1ed735671be615f842341a8))
* Update contributing links ([a1e1441](https://github.com/google/adk-python/commit/a1e14411159fd9f3e114e15b39b4949d0fd6ecb1))
* Use starred tuple unpacking on GCS artifact blob names ([3b1d9a8](https://github.com/google/adk-python/commit/3b1d9a8a3e631ca2d86d30f09640497f1728986c))
### Chore
* Do not send api request when session does not have events ([88a4402](https://github.com/google/adk-python/commit/88a4402d142672171d0a8ceae74671f47fa14289))
* Leverage official uv action for install([09f1269](https://github.com/google/adk-python/commit/09f1269bf7fa46ab4b9324e7f92b4f70ffc923e5))
* Update google-genai package and related deps to latest([ed7a21e](https://github.com/google/adk-python/commit/ed7a21e1890466fcdf04f7025775305dc71f603d))
* Add credential service backed by session state([29cd183](https://github.com/google/adk-python/commit/29cd183aa1b47dc4f5d8afe22f410f8546634abc))
* Clarify the behavior of Event.invocation_id([f033e40](https://github.com/google/adk-python/commit/f033e405c10ff8d86550d1419a9d63c0099182f9))
* Send user message to the agent that returned a corresponding function call if user message is a function response([7c670f6](https://github.com/google/adk-python/commit/7c670f638bc17374ceb08740bdd057e55c9c2e12))
* Add request converter to convert a2a request to ADK request([fb13963](https://github.com/google/adk-python/commit/fb13963deda0ff0650ac27771711ea0411474bf5))
* Support allow_origins in cloud_run deployment ([2fd8feb](https://github.com/google/adk-python/commit/2fd8feb65d6ae59732fb3ec0652d5650f47132cc))
## [1.4.2](https://github.com/google/adk-python/compare/v1.4.1...v1.4.2) (2025-06-20)
### Bug Fixes
* Add type checking to handle different response type of genai API client ([4d72d31](https://github.com/google/adk-python/commit/4d72d31b13f352245baa72b78502206dcbe25406))
* This fixes the broken VertexAiSessionService
* Allow more credentials types for BigQuery tools ([2f716ad](https://github.com/google/adk-python/commit/2f716ada7fbcf8e03ff5ae16ce26a80ca6fd7bf6))
## [1.4.1](https://github.com/google/adk-python/compare/v1.3.0...v1.4.1) (2025-06-18)
### Features
* Add Authenticated Tool (Experimental) ([dcea776](https://github.com/google/adk-python/commit/dcea7767c67c7edfb694304df32dca10b74c9a71))
* Add enable_affective_dialog and proactivity to run_config and llm_request ([fe1d5aa](https://github.com/google/adk-python/commit/fe1d5aa439cc56b89d248a52556c0a9b4cbd15e4))
* Add import session API in the fast API ([233fd20](https://github.com/google/adk-python/commit/233fd2024346abd7f89a16c444de0cf26da5c1a1))
* Add integration tests for litellm with and without turning on add_function_to_prompt ([8e28587](https://github.com/google/adk-python/commit/8e285874da7f5188ea228eb4d7262dbb33b1ae6f))
* Allow data_store_specs pass into ADK VAIS built-in tool ([675faef](https://github.com/google/adk-python/commit/675faefc670b5cd41991939fe0fc604df331111a))
* Enable MCP Tool Auth (Experimental) ([157d9be](https://github.com/google/adk-python/commit/157d9be88d92f22320604832e5a334a6eb81e4af))
* Implement GcsEvalSetResultsManager to handle storage of eval sets on GCS, and refactor eval set results manager ([0a5cf45](https://github.com/google/adk-python/commit/0a5cf45a75aca7b0322136b65ca5504a0c3c7362))
* Re-factor some eval sets manager logic, and implement GcsEvalSetsManager to handle storage of eval sets on GCS ([1551bd4](https://github.com/google/adk-python/commit/1551bd4f4d7042fffb497d9308b05f92d45d818f))
* Support real time input config ([d22920b](https://github.com/google/adk-python/commit/d22920bd7f827461afd649601326b0c58aea6716))
* Support refresh access token automatically for rest_api_tool ([1779801](https://github.com/google/adk-python/commit/177980106b2f7be9a8c0a02f395ff0f85faa0c5a))
### Bug Fixes
* Fix Agent generate config err ([#1305](https://github.com/google/adk-python/issues/1305)) ([badbcbd](https://github.com/google/adk-python/commit/badbcbd7a464e6b323cf3164d2bcd4e27cbc057f))
* Fix Agent generate config error ([#1450](https://github.com/google/adk-python/issues/1450)) ([694b712](https://github.com/google/adk-python/commit/694b71256c631d44bb4c4488279ea91d82f43e26))
* Fix liteLLM test failures ([fef8778](https://github.com/google/adk-python/commit/fef87784297b806914de307f48c51d83f977298f))
* Fix tracing for live ([58e07ca](https://github.com/google/adk-python/commit/58e07cae83048d5213d822be5197a96be9ce2950))
* Merge custom http options with adk specific http options in model api request ([4ccda99](https://github.com/google/adk-python/commit/4ccda99e8ec7aa715399b4b83c3f101c299a95e8))
* Remove unnecessary double quote on Claude docstring ([bbceb4f](https://github.com/google/adk-python/commit/bbceb4f2e89f720533b99cf356c532024a120dc4))
* Set explicit project in the BigQuery client ([6d174eb](https://github.com/google/adk-python/commit/6d174eba305a51fcf2122c0fd481378752d690ef))
* Support streaming in litellm + adk and add corresponding integration tests ([aafa80b](https://github.com/google/adk-python/commit/aafa80bd85a49fb1c1a255ac797587cffd3fa567))
* Support project-based gemini model path to use google_search_tool ([b2fc774](https://github.com/google/adk-python/commit/b2fc7740b363a4e33ec99c7377f396f5cee40b5a))
* Update conversion between Celsius and Fahrenheit ([1ae176a](https://github.com/google/adk-python/commit/1ae176ad2fa2b691714ac979aec21f1cf7d35e45))
### Chores
* Set `agent_engine_id` in the VertexAiSessionService constructor, also use the `agent_engine_id` field instead of overriding `app_name` in FastAPI endpoint ([fc65873](https://github.com/google/adk-python/commit/fc65873d7c31be607f6cd6690f142a031631582a))
## [1.3.0](https://github.com/google/adk-python/compare/v1.2.1...v1.3.0) (2025-06-11)
+1 -1
View File
@@ -200,7 +200,7 @@ For any changes that impact user-facing documentation (guides, API reference, tu
## Contributing Resources
[Contributing folder](https://github.com/google/adk-python/tree/main/contributing/samples) has resources that is helpful for contributors.
[Contributing folder](https://github.com/google/adk-python/tree/main/contributing) has resources that is helpful for contributors.
## Code reviews
+1 -1
View File
@@ -135,7 +135,7 @@ adk eval \
## 🤝 Contributing
We welcome contributions from the community! Whether it's bug reports, feature requests, documentation improvements, or code contributions, please see our
- [General contribution guideline and flow](https://google.github.io/adk-docs/contributing-guide/#questions).
- [General contribution guideline and flow](https://google.github.io/adk-docs/contributing-guide/).
- Then if you want to contribute code, please read [Code Contributing Guidelines](./CONTRIBUTING.md) to get started.
## đź“„ License
@@ -0,0 +1,241 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from pathlib import Path
from typing import Any
from adk_issue_formatting_agent.settings import GITHUB_BASE_URL
from adk_issue_formatting_agent.settings import IS_INTERACTIVE
from adk_issue_formatting_agent.settings import OWNER
from adk_issue_formatting_agent.settings import REPO
from adk_issue_formatting_agent.utils import error_response
from adk_issue_formatting_agent.utils import get_request
from adk_issue_formatting_agent.utils import post_request
from adk_issue_formatting_agent.utils import read_file
from google.adk import Agent
import requests
BUG_REPORT_TEMPLATE = read_file(
Path(__file__).parent / "../../../../.github/ISSUE_TEMPLATE/bug_report.md"
)
FREATURE_REQUEST_TEMPLATE = read_file(
Path(__file__).parent
/ "../../../../.github/ISSUE_TEMPLATE/feature_request.md"
)
APPROVAL_INSTRUCTION = (
"**Do not** wait or ask for user approval or confirmation for adding the"
" comment."
)
if IS_INTERACTIVE:
APPROVAL_INSTRUCTION = (
"Ask for user approval or confirmation for adding the comment."
)
def list_open_issues(issue_count: int) -> dict[str, Any]:
"""List most recent `issue_count` numer of open issues in the repo.
Args:
issue_count: number of issues to return
Returns:
The status of this request, with a list of issues when successful.
"""
url = f"{GITHUB_BASE_URL}/search/issues"
query = f"repo:{OWNER}/{REPO} is:open is:issue"
params = {
"q": query,
"sort": "created",
"order": "desc",
"per_page": issue_count,
"page": 1,
}
try:
response = get_request(url, params)
except requests.exceptions.RequestException as e:
return error_response(f"Error: {e}")
issues = response.get("items", None)
return {"status": "success", "issues": issues}
def get_issue(issue_number: int) -> dict[str, Any]:
"""Get the details of the specified issue number.
Args:
issue_number: issue number of the Github issue.
Returns:
The status of this request, with the issue details when successful.
"""
url = f"{GITHUB_BASE_URL}/repos/{OWNER}/{REPO}/issues/{issue_number}"
try:
response = get_request(url)
except requests.exceptions.RequestException as e:
return error_response(f"Error: {e}")
return {"status": "success", "issue": response}
def add_comment_to_issue(issue_number: int, comment: str) -> dict[str, any]:
"""Add the specified comment to the given issue number.
Args:
issue_number: issue number of the Github issue
comment: comment to add
Returns:
The the status of this request, with the applied comment when successful.
"""
print(f"Attempting to add comment '{comment}' to issue #{issue_number}")
url = f"{GITHUB_BASE_URL}/repos/{OWNER}/{REPO}/issues/{issue_number}/comments"
payload = {"body": comment}
try:
response = post_request(url, payload)
except requests.exceptions.RequestException as e:
return error_response(f"Error: {e}")
return {
"status": "success",
"added_comment": response,
}
def list_comments_on_issue(issue_number: int) -> dict[str, any]:
"""List all comments on the given issue number.
Args:
issue_number: issue number of the Github issue
Returns:
The the status of this request, with the list of comments when successful.
"""
print(f"Attempting to list comments on issue #{issue_number}")
url = f"{GITHUB_BASE_URL}/repos/{OWNER}/{REPO}/issues/{issue_number}/comments"
try:
response = get_request(url)
except requests.exceptions.RequestException as e:
return error_response(f"Error: {e}")
return {"status": "success", "comments": response}
root_agent = Agent(
model="gemini-2.5-pro",
name="adk_issue_formatting_assistant",
description="Check ADK issue format and content.",
instruction=f"""
# 1. IDENTITY
You are an AI assistant designed to help maintain the quality and consistency of issues in our GitHub repository.
Your primary role is to act as a "GitHub Issue Format Validator." You will analyze new and existing **open** issues
to ensure they contain all the necessary information as required by our templates. You are helpful, polite,
and precise in your feedback.
# 2. CONTEXT & RESOURCES
* **Repository:** You are operating on the GitHub repository `{OWNER}/{REPO}`.
* **Bug Report Template:** (`{BUG_REPORT_TEMPLATE}`)
* **Feature Request Template:** (`{FREATURE_REQUEST_TEMPLATE}`)
# 3. CORE MISSION
Your goal is to check if a GitHub issue, identified as either a "bug" or a "feature request,"
contains all the information required by the corresponding template. If it does not, your job is
to post a single, helpful comment asking the original author to provide the missing information.
{APPROVAL_INSTRUCTION}
**IMPORTANT NOTE:**
* You add one comment at most each time you are invoked.
* Don't proceed to other issues which are not the target issues.
* Don't take any action on closed issues.
# 4. BEHAVIORAL RULES & LOGIC
## Step 1: Identify Issue Type & Applicability
Your first task is to determine if the issue is a valid target for validation.
1. **Assess Content Intent:** You must perform a quick semantic check of the issue's title, body, and comments.
If you determine the issue's content is fundamentally *not* a bug report or a feature request
(for example, it is a general question, a request for help, or a discussion prompt), then you must ignore it.
2. **Exit Condition:** If the issue does not clearly fall into the categories of "bug" or "feature request"
based on both its labels and its content, **take no action**.
## Step 2: Analyze the Issue Content
If you have determined the issue is a valid bug or feature request, your analysis depends on whether it has comments.
**Scenario A: Issue has NO comments**
1. Read the main body of the issue.
2. Compare the content of the issue body against the required headings/sections in the relevant template (Bug or Feature).
3. Check for the presence of content under each heading. A heading with no content below it is considered incomplete.
4. If one or more sections are missing or empty, proceed to Step 3.
5. If all sections are filled out, your task is complete. Do nothing.
**Scenario B: Issue HAS one or more comments**
1. First, analyze the main issue body to see which sections of the template are filled out.
2. Next, read through **all** the comments in chronological order.
3. As you read the comments, check if the information provided in them satisfies any of the template sections that were missing from the original issue body.
4. After analyzing the body and all comments, determine if any required sections from the template *still* remain unaddressed.
5. If one or more sections are still missing information, proceed to Step 3.
6. If the issue body and comments *collectively* provide all the required information, your task is complete. Do nothing.
## Step 3: Formulate and Post a Comment (If Necessary)
If you determined in Step 2 that information is missing, you must post a **single comment** on the issue.
Please include a bolded note in your comment that this comment was added by an ADK agent.
**Comment Guidelines:**
* **Be Polite and Helpful:** Start with a friendly tone.
* **Be Specific:** Clearly list only the sections from the template that are still missing. Do not list sections that have already been filled out.
* **Address the Author:** Mention the issue author by their username (e.g., `@username`).
* **Provide Context:** Explain *why* the information is needed (e.g., "to help us reproduce the bug" or "to better understand your request").
* **Do not be repetitive:** If you have already commented on an issue asking for information, do not comment again unless new information has been added and it's still incomplete.
**Example Comment for a Bug Report:**
> **Response from ADK Agent**
>
> Hello @[issue-author-username], thank you for submitting this issue!
>
> To help us investigate and resolve this bug effectively, could you please provide the missing details for the following sections of our bug report template:
>
> * **To Reproduce:** (Please provide the specific steps required to reproduce the behavior)
> * **Desktop (please complete the following information):** (Please provide OS, Python version, and ADK version)
>
> This information will give us the context we need to move forward. Thanks!
**Example Comment for a Feature Request:**
> **Response from ADK Agent**
>
> Hi @[issue-author-username], thanks for this great suggestion!
>
> To help our team better understand and evaluate your feature request, could you please provide a bit more information on the following section:
>
> * **Is your feature request related to a problem? Please describe.**
>
> We look forward to hearing more about your idea!
# 5. FINAL INSTRUCTION
Execute this process for the given GitHub issue. Your final output should either be **[NO ACTION]**
if the issue is complete or invalid, or **[POST COMMENT]** followed by the exact text of the comment you will post.
Please include your justification for your decision in your output.
""",
tools={
list_open_issues,
get_issue,
add_comment_to_issue,
list_comments_on_issue,
},
)
@@ -0,0 +1,33 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
from dotenv import load_dotenv
load_dotenv(override=True)
GITHUB_BASE_URL = "https://api.github.com"
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
if not GITHUB_TOKEN:
raise ValueError("GITHUB_TOKEN environment variable not set")
OWNER = os.getenv("OWNER", "google")
REPO = os.getenv("REPO", "adk-python")
EVENT_NAME = os.getenv("EVENT_NAME")
ISSUE_NUMBER = os.getenv("ISSUE_NUMBER")
ISSUE_COUNT_TO_PROCESS = os.getenv("ISSUE_COUNT_TO_PROCESS")
IS_INTERACTIVE = os.environ.get("INTERACTIVE", "1").lower() in ["true", "1"]
@@ -0,0 +1,53 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import Any
from adk_issue_formatting_agent.settings import GITHUB_TOKEN
import requests
headers = {
"Authorization": f"token {GITHUB_TOKEN}",
"Accept": "application/vnd.github.v3+json",
}
def get_request(
url: str, params: dict[str, Any] | None = None
) -> dict[str, Any]:
if params is None:
params = {}
response = requests.get(url, headers=headers, params=params, timeout=60)
response.raise_for_status()
return response.json()
def post_request(url: str, payload: Any) -> dict[str, Any]:
response = requests.post(url, headers=headers, json=payload, timeout=60)
response.raise_for_status()
return response.json()
def error_response(error_message: str) -> dict[str, Any]:
return {"status": "error", "message": error_message}
def read_file(file_path: str) -> str:
"""Read the content of the given file."""
try:
with open(file_path, "r") as f:
return f.read()
except FileNotFoundError:
print(f"Error: File not found: {file_path}.")
return ""
@@ -31,7 +31,7 @@ root_agent = Agent(
model='gemini-2.0-flash',
name='log_agent',
description='Log user query.',
instruction="""Always log the user query and reploy "kk, I've logged."
instruction="""Always log the user query and reply "kk, I've logged."
""",
tools=[log_query],
generate_content_config=types.GenerateContentConfig(
+19 -4
View File
@@ -40,13 +40,28 @@ would set:
### With Application Default Credentials
This mode is useful for quick development when the agent builder is the only
user interacting with the agent. The tools are initialized with the default
credentials present on the machine running the agent.
user interacting with the agent. The tools are run with these credentials.
1. Create application default credentials on the machine where the agent would
be running by following https://cloud.google.com/docs/authentication/provide-credentials-adc.
1. Set `RUN_WITH_ADC=True` in `agent.py` and run the agent
1. Set `CREDENTIALS_TYPE=None` in `agent.py`
1. Run the agent
### With Service Account Keys
This mode is useful for quick development when the agent builder wants to run
the agent with service account credentials. The tools are run with these
credentials.
1. Create service account key by following https://cloud.google.com/iam/docs/service-account-creds#user-managed-keys.
1. Set `CREDENTIALS_TYPE=AuthCredentialTypes.SERVICE_ACCOUNT` in `agent.py`
1. Download the key file and replace `"service_account_key.json"` with the path
1. Run the agent
### With Interactive OAuth
@@ -72,7 +87,7 @@ type.
Note: don't create a separate .env, instead put it to the same .env file that
stores your Vertex AI or Dev ML credentials
1. Set `RUN_WITH_ADC=False` in `agent.py` and run the agent
1. Set `CREDENTIALS_TYPE=AuthCredentialTypes.OAUTH2` in `agent.py` and run the agent
## Sample prompts
+20 -9
View File
@@ -15,24 +15,21 @@
import os
from google.adk.agents import llm_agent
from google.adk.auth import AuthCredentialTypes
from google.adk.tools.bigquery import BigQueryCredentialsConfig
from google.adk.tools.bigquery import BigQueryToolset
from google.adk.tools.bigquery.config import BigQueryToolConfig
from google.adk.tools.bigquery.config import WriteMode
import google.auth
RUN_WITH_ADC = False
# Define an appropriate credential type
CREDENTIALS_TYPE = AuthCredentialTypes.OAUTH2
# Define BigQuery tool config
tool_config = BigQueryToolConfig(write_mode=WriteMode.ALLOWED)
if RUN_WITH_ADC:
# Initialize the tools to use the application default credentials.
application_default_credentials, _ = google.auth.default()
credentials_config = BigQueryCredentialsConfig(
credentials=application_default_credentials
)
else:
if CREDENTIALS_TYPE == AuthCredentialTypes.OAUTH2:
# Initiaze the tools to do interactive OAuth
# The environment variables OAUTH_CLIENT_ID and OAUTH_CLIENT_SECRET
# must be set
@@ -40,6 +37,20 @@ else:
client_id=os.getenv("OAUTH_CLIENT_ID"),
client_secret=os.getenv("OAUTH_CLIENT_SECRET"),
)
elif CREDENTIALS_TYPE == AuthCredentialTypes.SERVICE_ACCOUNT:
# Initialize the tools to use the credentials in the service account key.
# If this flow is enabled, make sure to replace the file path with your own
# service account key file
# https://cloud.google.com/iam/docs/service-account-creds#user-managed-keys
creds, _ = google.auth.load_credentials_from_file("service_account_key.json")
credentials_config = BigQueryCredentialsConfig(credentials=creds)
else:
# Initialize the tools to use the application default credentials.
# https://cloud.google.com/docs/authentication/provide-credentials-adc
application_default_credentials, _ = google.auth.default()
credentials_config = BigQueryCredentialsConfig(
credentials=application_default_credentials
)
bigquery_toolset = BigQueryToolset(
credentials_config=credentials_config, bigquery_tool_config=tool_config
@@ -49,7 +60,7 @@ bigquery_toolset = BigQueryToolset(
# debug CLI
root_agent = llm_agent.Agent(
model="gemini-2.0-flash",
name="hello_agent",
name="bigquery_agent",
description=(
"Agent to answer questions about BigQuery data and models and execute"
" SQL queries."
@@ -1,45 +1,40 @@
# BigQuery Sample
# Google API Tools Sample
## Introduction
This sample tests and demos the BigQuery support in ADK via two tools:
This sample tests and demos Google API tools available in the
`google.adk.tools.google_api_tool` module. We pick the following BigQuery API
tools for this sample agent:
* 1. bigquery_datasets_list:
1. `bigquery_datasets_list`: List user's datasets.
List user's datasets.
2. `bigquery_datasets_get`: Get a dataset's details.
* 2. bigquery_datasets_get:
Get a dataset's details.
3. `bigquery_datasets_insert`: Create a new dataset.
* 3. bigquery_datasets_insert:
Create a new dataset.
4. `bigquery_tables_list`: List all tables in a dataset.
* 4. bigquery_tables_list:
List all tables in a dataset.
5. `bigquery_tables_get`: Get a table's details.
* 5. bigquery_tables_get:
Get a table's details.
* 6. bigquery_tables_insert:
Insert a new table into a dataset.
6. `bigquery_tables_insert`: Insert a new table into a dataset.
## How to use
* 1. Follow https://developers.google.com/identity/protocols/oauth2#1.-obtain-oauth-2.0-credentials-from-the-dynamic_data.setvar.console_name. to get your client id and client secret.
1. Follow https://developers.google.com/identity/protocols/oauth2#1.-obtain-oauth-2.0-credentials-from-the-dynamic_data.setvar.console_name. to get your client id and client secret.
Be sure to choose "web" as your client type.
* 2. Configure your `.env` file to add two variables:
2. Configure your `.env` file to add two variables:
* OAUTH_CLIENT_ID={your client id}
* OAUTH_CLIENT_SECRET={your client secret}
Note: don't create a separate `.env` file , instead put it to the same `.env` file that stores your Vertex AI or Dev ML credentials
* 3. Follow https://developers.google.com/identity/protocols/oauth2/web-server#creatingcred to add http://localhost/dev-ui/ to "Authorized redirect URIs".
3. Follow https://developers.google.com/identity/protocols/oauth2/web-server#creatingcred to add http://localhost/dev-ui/ to "Authorized redirect URIs".
Note: localhost here is just a hostname that you use to access the dev ui, replace it with the actual hostname you use to access the dev ui.
* 4. For 1st run, allow popup for localhost in Chrome.
4. For 1st run, allow popup for localhost in Chrome.
## Sample prompt
@@ -0,0 +1,15 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from . import agent
@@ -40,7 +40,7 @@ bigquery_toolset = BigQueryToolset(
root_agent = Agent(
model="gemini-2.0-flash",
name="bigquery_agent",
name="google_api_bigquery_agent",
instruction="""
You are a helpful Google BigQuery agent that help to manage users' data on Google BigQuery.
Use the provided tools to conduct various operations on users' data in Google BigQuery.
@@ -0,0 +1,16 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from . import agent
@@ -0,0 +1,78 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import random
from google.adk import Agent
from google.adk.models.lite_llm import LiteLlm
from langchain_core.utils.function_calling import convert_to_openai_function
def roll_die(sides: int) -> int:
"""Roll a die and return the rolled result.
Args:
sides: The integer number of sides the die has.
Returns:
An integer of the result of rolling the die.
"""
return random.randint(1, sides)
def check_prime(number: int) -> str:
"""Check if a given number is prime.
Args:
number: The input number to check.
Returns:
A str indicating the number is prime or not.
"""
if number <= 1:
return f"{number} is not prime."
is_prime = True
for i in range(2, int(number**0.5) + 1):
if number % i == 0:
is_prime = False
break
if is_prime:
return f"{number} is prime."
else:
return f"{number} is not prime."
root_agent = Agent(
model=LiteLlm(
model="vertex_ai/meta/llama-4-maverick-17b-128e-instruct-maas",
# If the model is not trained with functions and you would like to
# enable function calling, you can add functions to the models, and the
# functions will be added to the prompts during inferences.
functions=[
convert_to_openai_function(roll_die),
convert_to_openai_function(check_prime),
],
),
name="data_processing_agent",
description="""You are a helpful assistant.""",
instruction="""
You are a helpful assistant, and call tools optionally.
If call tools, the tool format should be in json, and the tool arguments should be parsed from users inputs.
""",
tools=[
roll_die,
check_prime,
],
)
@@ -0,0 +1,81 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import asyncio
import time
import agent
from dotenv import load_dotenv
from google.adk import Runner
from google.adk.artifacts import InMemoryArtifactService
from google.adk.cli.utils import logs
from google.adk.sessions import InMemorySessionService
from google.adk.sessions import Session
from google.genai import types
load_dotenv(override=True)
logs.log_to_tmp_folder()
async def main():
app_name = 'my_app'
user_id_1 = 'user1'
session_service = InMemorySessionService()
artifact_service = InMemoryArtifactService()
runner = Runner(
app_name=app_name,
agent=agent.root_agent,
artifact_service=artifact_service,
session_service=session_service,
)
session_11 = await session_service.create_session(
app_name=app_name, user_id=user_id_1
)
async def run_prompt(session: Session, new_message: str):
content = types.Content(
role='user', parts=[types.Part.from_text(text=new_message)]
)
print('** User says:', content.model_dump(exclude_none=True))
async for event in runner.run_async(
user_id=user_id_1,
session_id=session.id,
new_message=content,
):
if event.content.parts:
part = event.content.parts[0]
if part.text:
print(f'** {event.author}: {part.text}')
if part.function_call:
print(f'** {event.author} calls tool: {part.function_call}')
if part.function_response:
print(
f'** {event.author} gets tool response: {part.function_response}'
)
start_time = time.time()
print('Start time:', start_time)
print('------------------------------------')
await run_prompt(session_11, 'Hi, introduce yourself.')
await run_prompt(session_11, 'Roll a die with 100 sides.')
await run_prompt(session_11, 'Check if it is prime.')
end_time = time.time()
print('------------------------------------')
print('End time:', end_time)
print('Total time:', end_time - start_time)
if __name__ == '__main__':
asyncio.run(main())
+2 -2
View File
@@ -16,8 +16,8 @@
import os
from google.adk.agents.llm_agent import LlmAgent
from google.adk.tools.mcp_tool.mcp_session_manager import SseConnectionParams
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset
from google.adk.tools.mcp_tool.mcp_toolset import SseServerParams
_allowed_path = os.path.dirname(os.path.abspath(__file__))
@@ -31,7 +31,7 @@ Allowed directory: {_allowed_path}
""",
tools=[
MCPToolset(
connection_params=SseServerParams(
connection_params=SseConnectionParams(
url='http://localhost:3000/sse',
headers={'Accept': 'text/event-stream'},
),

Some files were not shown because too many files have changed in this diff Show More