Skip to content

Commit 58379a5

Browse files
authored
Merge branch 'main' into use-starred-tuple-unpacking-on-gcs-artifact-blob-names-versions
2 parents b7771e9 + 37108be commit 58379a5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+8599
-565
lines changed

.gemini/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"contextFileName": "AGENTS.md"
3+
}

.github/workflows/pr-commit-check.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# .github/workflows/pr-commit-check.yml
2+
# This GitHub Action workflow checks if a pull request has more than one commit.
3+
# If it does, it fails the check and instructs the user to squash their commits.
4+
5+
name: 'PR Commit Check'
6+
7+
# This workflow runs on pull request events.
8+
# It's configured to run on any pull request that is opened or synchronized (new commits pushed).
9+
on:
10+
pull_request:
11+
types: [opened, synchronize]
12+
13+
# Defines the jobs that will run as part of the workflow.
14+
jobs:
15+
check-commit-count:
16+
# The type of runner that the job will run on. 'ubuntu-latest' is a good default.
17+
runs-on: ubuntu-latest
18+
19+
# The steps that will be executed as part of the job.
20+
steps:
21+
# Step 1: Check out the code
22+
# This action checks out your repository under $GITHUB_WORKSPACE, so your workflow can access it.
23+
- name: Checkout Code
24+
uses: actions/checkout@v4
25+
with:
26+
# We need to fetch all commits to accurately count them.
27+
# '0' means fetch all history for all branches and tags.
28+
fetch-depth: 0
29+
30+
# Step 2: Count the commits in the pull request
31+
# This step runs a script to get the number of commits in the PR.
32+
- name: Count Commits
33+
id: count_commits
34+
# We use `git rev-list --count` to count the commits.
35+
# ${{ github.event.pull_request.base.sha }} is the commit SHA of the base branch.
36+
# ${{ github.event.pull_request.head.sha }} is the commit SHA of the head branch (the PR branch).
37+
# The '..' syntax gives us the list of commits in the head branch that are not in the base branch.
38+
# The output of the command (the count) is stored in a step output variable named 'count'.
39+
run: |
40+
count=$(git rev-list --count ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }})
41+
echo "commit_count=$count" >> $GITHUB_OUTPUT
42+
43+
# Step 3: Check if the commit count is greater than 1
44+
# This step uses the output from the previous step to decide whether to pass or fail.
45+
- name: Check Commit Count
46+
# This step only runs if the 'commit_count' output from the 'count_commits' step is greater than 1.
47+
if: steps.count_commits.outputs.commit_count > 1
48+
# If the condition is met, the workflow will exit with a failure status.
49+
run: |
50+
echo "This pull request has ${{ steps.count_commits.outputs.commit_count }} commits."
51+
echo "Please squash them into a single commit before merging."
52+
echo "You can use git rebase -i HEAD~N"
53+
echo "...where N is the number of commits you want to squash together. The PR check conveniently tells you this number! For example, if the check says you have 3 commits, you would run: git rebase -i HEAD~3."
54+
echo "Because you have rewritten the commit history, you must use the --force flag to update the pull request: git push --force"
55+
exit 1
56+
57+
# Step 4: Success message
58+
# This step runs if the commit count is not greater than 1 (i.e., it's 1).
59+
- name: Success
60+
if: steps.count_commits.outputs.commit_count <= 1
61+
run: |
62+
echo "This pull request has a single commit. Great job!"

.github/workflows/triage.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,5 @@ jobs:
4040
ISSUE_TITLE: ${{ github.event.issue.title }}
4141
ISSUE_BODY: ${{ github.event.issue.body }}
4242
ISSUE_COUNT_TO_PROCESS: '3' # Process 3 issues at a time on schedule
43-
run: python contributing/samples/adk_triaging_agent/main.py
43+
PYTHONPATH: contributing/samples
44+
run: python -m adk_triaging_agent.main

AGENTS.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Gemini CLI / Gemini Code Assist Context
2+
3+
This document provides context for the Gemini CLI and Gemini Code Assist to understand the project and assist with development.
4+
5+
## Project Overview
6+
7+
The Agent Development Kit (ADK) is an open-source, code-first Python toolkit for building, evaluating, and deploying sophisticated AI agents with flexibility and control. While optimized for Gemini and the Google ecosystem, ADK is model-agnostic, deployment-agnostic, and is built for compatibility with other frameworks. ADK was designed to make agent development feel more like software development, to make it easier for developers to create, deploy, and orchestrate agentic architectures that range from simple tasks to complex workflows.
8+
9+
## ADK: Style Guides
10+
11+
### Python Style Guide
12+
13+
The project follows the Google Python Style Guide. Key conventions are enforced using `pylint` with the provided `pylintrc` configuration file. Here are some of the key style points:
14+
15+
* **Indentation**: 2 spaces.
16+
* **Line Length**: Maximum 80 characters.
17+
* **Naming Conventions**:
18+
* `function_and_variable_names`: `snake_case`
19+
* `ClassNames`: `CamelCase`
20+
* `CONSTANTS`: `UPPERCASE_SNAKE_CASE`
21+
* **Docstrings**: Required for all public modules, functions, classes, and methods.
22+
* **Imports**: Organized and sorted.
23+
* **Error Handling**: Specific exceptions should be caught, not general ones like `Exception`.
24+
25+
### Autoformat
26+
27+
We have autoformat.sh to help solve import organize and formatting issues.
28+
29+
```bash
30+
# Run in open_source_workspace/
31+
$ ./autoformat.sh
32+
```
33+
34+
### In ADK source
35+
36+
Below styles applies to the ADK source code (under `src/` folder of the Github.
37+
repo).
38+
39+
#### Use relative imports
40+
41+
```python
42+
# DO
43+
from ..agents.llm_agent import LlmAgent
44+
45+
# DON'T
46+
from google.adk.agents.llm_agent import LlmAgent
47+
```
48+
49+
#### Import from module, not from `__init__.py`
50+
51+
```python
52+
# DO
53+
from ..agents.llm_agent import LlmAgent
54+
55+
# DON'T
56+
from ..agents import LlmAgent # import from agents/__init__.py
57+
```
58+
59+
#### Always do `from __future__ import annotations`
60+
61+
```python
62+
# DO THIS, right after the open-source header.
63+
from __future__ import annotations
64+
```
65+
66+
Like below:
67+
68+
```python
69+
# Copyright 2025 Google LLC
70+
#
71+
# Licensed under the Apache License, Version 2.0 (the "License");
72+
# you may not use this file except in compliance with the License.
73+
# You may obtain a copy of the License at
74+
#
75+
# http://www.apache.org/licenses/LICENSE-2.0
76+
#
77+
# Unless required by applicable law or agreed to in writing, software
78+
# distributed under the License is distributed on an "AS IS" BASIS,
79+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80+
# See the License for the specific language governing permissions and
81+
# limitations under the License.
82+
83+
from __future__ import annotations
84+
85+
# ... the rest of the file.
86+
```
87+
88+
This allows us to forward-reference a class without quotes.
89+
90+
Check out go/pep563 for details.
91+
92+
### In ADK tests
93+
94+
#### Use absolute imports
95+
96+
In tests, we use `google.adk` same as how our users uses.
97+
98+
```python
99+
# DO
100+
from google.adk.agents.llm_agent import LlmAgent
101+
102+
# DON'T
103+
from ..agents.llm_agent import LlmAgent
104+
```
105+
106+
## ADK: Local testing
107+
108+
### Unit tests
109+
110+
Run below command:
111+
112+
```bash
113+
$ pytest tests/unittests
114+
```

CONTRIBUTING.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ This project follows
4949

5050
## Requirement for PRs
5151

52+
- Each PR should only have one commit. Please squash it if there are multiple PRs.
5253
- All PRs, other than small documentation or typo fixes, should have a Issue assoicated. If not, please create one.
5354
- Small, focused PRs. Keep changes minimal—one concern per PR.
5455
- For bug fixes or features, please provide logs or screenshot after the fix is applied to help reviewers better understand the fix.
@@ -147,11 +148,11 @@ For any changes that impact user-facing documentation (guides, API reference, tu
147148
pytest ./tests/unittests
148149
```
149150

150-
NOTE: for accurately repro test failure, only include `test` and `eval` as
151-
extra dependencies.
151+
NOTE: for accurate repro of test failure, only include `test`, `eval` and
152+
`a2a` as extra dependencies.
152153

153154
```shell
154-
uv sync --extra test --extra eval
155+
uv sync --extra test --extra eval --extra a2a
155156
pytest ./tests/unittests
156157
```
157158

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# A2A OAuth Authentication Sample Agent
2+
3+
This sample demonstrates the **Agent-to-Agent (A2A)** architecture with **OAuth Authentication** workflows in the Agent Development Kit (ADK). The sample implements a multi-agent system where a remote agent can surface OAuth authentication requests to the local agent, which then guides the end user through the OAuth flow before returning the authentication credentials to the remote agent for API access.
4+
5+
## Overview
6+
7+
The A2A OAuth Authentication sample consists of:
8+
9+
- **Root Agent** (`root_agent`): The main orchestrator that handles user requests and delegates tasks to specialized agents
10+
- **YouTube Search Agent** (`youtube_search_agent`): A local agent that handles YouTube video searches using LangChain tools
11+
- **BigQuery Agent** (`bigquery_agent`): A remote A2A agent that manages BigQuery operations and requires OAuth authentication for Google Cloud access
12+
13+
## Architecture
14+
15+
```
16+
┌─────────────────┐ ┌────────────────────┐ ┌──────────────────┐
17+
│ End User │───▶│ Root Agent │───▶│ BigQuery Agent │
18+
│ (OAuth Flow) │ │ (Local) │ │ (Remote A2A) │
19+
│ │ │ │ │ (localhost:8001) │
20+
│ OAuth UI │◀───│ │◀───│ OAuth Request │
21+
└─────────────────┘ └────────────────────┘ └──────────────────┘
22+
```
23+
24+
## Key Features
25+
26+
### 1. **Multi-Agent Architecture**
27+
- Root agent coordinates between local YouTube search and remote BigQuery operations
28+
- Demonstrates hybrid local/remote agent workflows
29+
- Seamless task delegation based on user request types
30+
31+
### 2. **OAuth Authentication Workflow**
32+
- Remote BigQuery agent surfaces OAuth authentication requests to the root agent
33+
- Root agent guides end users through Google OAuth flow for BigQuery access
34+
- Secure token exchange between agents for authenticated API calls
35+
36+
### 3. **Google Cloud Integration**
37+
- BigQuery toolset with comprehensive dataset and table management capabilities
38+
- OAuth-protected access to user's Google Cloud BigQuery resources
39+
- Support for listing, creating, and managing datasets and tables
40+
41+
### 4. **LangChain Tool Integration**
42+
- YouTube search functionality using LangChain community tools
43+
- Demonstrates integration of third-party tools in agent workflows
44+
45+
## Setup and Usage
46+
47+
### Prerequisites
48+
49+
1. **Set up OAuth Credentials**:
50+
```bash
51+
export OAUTH_CLIENT_ID=your_google_oauth_client_id
52+
export OAUTH_CLIENT_SECRET=your_google_oauth_client_secret
53+
```
54+
55+
2. **Start the Remote BigQuery Agent server**:
56+
```bash
57+
# Start the remote a2a server that serves the BigQuery agent on port 8001
58+
adk api_server --a2a --port 8001 contributing/samples/a2a_auth/remote_a2a
59+
```
60+
61+
3. **Run the Main Agent**:
62+
```bash
63+
# In a separate terminal, run the adk web server
64+
adk web contributing/samples/
65+
```
66+
67+
### Example Interactions
68+
69+
Once both services are running, you can interact with the root agent:
70+
71+
**YouTube Search (No Authentication Required):**
72+
```
73+
User: Search for 3 Taylor Swift music videos
74+
Agent: I'll help you search for Taylor Swift music videos on YouTube.
75+
[Agent delegates to YouTube Search Agent]
76+
Agent: I found 3 Taylor Swift music videos:
77+
1. "Anti-Hero" - Official Music Video
78+
2. "Shake It Off" - Official Music Video
79+
3. "Blank Space" - Official Music Video
80+
```
81+
82+
**BigQuery Operations (OAuth Required):**
83+
```
84+
User: List my BigQuery datasets
85+
Agent: I'll help you access your BigQuery datasets. This requires authentication with your Google account.
86+
[Agent delegates to BigQuery Agent]
87+
Agent: To access your BigQuery data, please complete the OAuth authentication.
88+
[OAuth flow initiated - user redirected to Google authentication]
89+
User: [Completes OAuth flow in browser]
90+
Agent: Authentication successful! Here are your BigQuery datasets:
91+
- dataset_1: Customer Analytics
92+
- dataset_2: Sales Data
93+
- dataset_3: Marketing Metrics
94+
```
95+
96+
**Dataset Management:**
97+
```
98+
User: Show me details for my Customer Analytics dataset
99+
Agent: I'll get the details for your Customer Analytics dataset.
100+
[Using existing OAuth token]
101+
Agent: Customer Analytics Dataset Details:
102+
- Created: 2024-01-15
103+
- Location: US
104+
- Tables: 5
105+
- Description: Customer behavior and analytics data
106+
```
107+
108+
## Code Structure
109+
110+
### Main Agent (`agent.py`)
111+
112+
- **`youtube_search_agent`**: Local agent with LangChain YouTube search tool
113+
- **`bigquery_agent`**: Remote A2A agent configuration for BigQuery operations
114+
- **`root_agent`**: Main orchestrator with task delegation logic
115+
116+
### Remote BigQuery Agent (`remote_a2a/bigquery_agent/`)
117+
118+
- **`agent.py`**: Implementation of the BigQuery agent with OAuth toolset
119+
- **`agent.json`**: Agent card of the A2A agent
120+
- **`BigQueryToolset`**: OAuth-enabled tools for BigQuery dataset and table management
121+
122+
## OAuth Authentication Workflow
123+
124+
The OAuth authentication process follows this pattern:
125+
126+
1. **Initial Request**: User requests BigQuery operation through root agent
127+
2. **Delegation**: Root agent delegates to remote BigQuery agent
128+
3. **Auth Check**: BigQuery agent checks for valid OAuth token
129+
4. **Auth Request**: If no token, agent surfaces OAuth request to root agent
130+
5. **User OAuth**: Root agent guides user through Google OAuth flow
131+
6. **Token Exchange**: Root agent sends OAuth token to BigQuery agent
132+
7. **API Call**: BigQuery agent uses token to make authenticated API calls
133+
8. **Result Return**: BigQuery agent returns results through root agent to user
134+
135+
## Supported BigQuery Operations
136+
137+
The BigQuery agent supports the following operations:
138+
139+
### Dataset Operations:
140+
- **List Datasets**: `bigquery_datasets_list` - Get all user's datasets
141+
- **Get Dataset**: `bigquery_datasets_get` - Get specific dataset details
142+
- **Create Dataset**: `bigquery_datasets_insert` - Create new dataset
143+
144+
### Table Operations:
145+
- **List Tables**: `bigquery_tables_list` - Get tables in a dataset
146+
- **Get Table**: `bigquery_tables_get` - Get specific table details
147+
- **Create Table**: `bigquery_tables_insert` - Create new table in dataset
148+
149+
## Extending the Sample
150+
151+
You can extend this sample by:
152+
153+
- Adding more Google Cloud services (Cloud Storage, Compute Engine, etc.)
154+
- Implementing token refresh and expiration handling
155+
- Adding role-based access control for different BigQuery operations
156+
- Creating OAuth flows for other providers (Microsoft, Facebook, etc.)
157+
- Adding audit logging for authentication events
158+
- Implementing multi-tenant OAuth token management
159+
160+
## Troubleshooting
161+
162+
**Connection Issues:**
163+
- Ensure the local ADK web server is running on port 8000
164+
- Ensure the remote A2A server is running on port 8001
165+
- Check that no firewall is blocking localhost connections
166+
- Verify the agent.json URL matches the running A2A server
167+
168+
**OAuth Issues:**
169+
- Verify OAuth client ID and secret are correctly set in .env file
170+
- Ensure OAuth redirect URIs are properly configured in Google Cloud Console
171+
- Check that the OAuth scopes include BigQuery access permissions
172+
- Verify the user has access to the BigQuery projects/datasets
173+
174+
**BigQuery Access Issues:**
175+
- Ensure the authenticated user has BigQuery permissions
176+
- Check that the Google Cloud project has BigQuery API enabled
177+
- Verify dataset and table names are correct and accessible
178+
- Check for quota limits on BigQuery API calls
179+
180+
**Agent Communication Issues:**
181+
- Check the logs for both the local ADK web server and remote A2A server
182+
- Verify OAuth tokens are properly passed between agents
183+
- Ensure agent instructions are clear about authentication requirements

0 commit comments

Comments
 (0)