From 62a543bd58d718a72581688edb01f542745db770 Mon Sep 17 00:00:00 2001 From: Google Team Member Date: Tue, 20 May 2025 21:44:55 -0700 Subject: [PATCH] Add dynamicAuthConfig to ExecuteCustomQuery. Add sample agent for ApplicationIntegrationToolset which uses Integration Connectors with end user credentials. PiperOrigin-RevId: 761356343 --- .../integration_connector_euc_agent/README.md | 75 +++++++++++++++ .../__init__.py | 1 + .../integration_connector_euc_agent/agent.py | 95 +++++++++++++++++++ .../clients/connections_client.py | 3 + 4 files changed, 174 insertions(+) create mode 100644 contributing/samples/integration_connector_euc_agent/README.md create mode 100644 contributing/samples/integration_connector_euc_agent/__init__.py create mode 100644 contributing/samples/integration_connector_euc_agent/agent.py diff --git a/contributing/samples/integration_connector_euc_agent/README.md b/contributing/samples/integration_connector_euc_agent/README.md new file mode 100644 index 0000000..8bcac85 --- /dev/null +++ b/contributing/samples/integration_connector_euc_agent/README.md @@ -0,0 +1,75 @@ +# Application Integration Agent Sample with End-User Credentials + +## Introduction + +This sample demonstrates how to use the `ApplicationIntegrationToolset` within +an ADK agent to interact with external applications using **end-user OAuth 2.0 +credentials**. Specifically, this agent (`agent.py`) is configured to interact +with Google Calendar using a pre-configured Application Integration connection +and authenticating as the end user. + +## Prerequisites + +1. **Set up Integration Connection:** + * You need an existing + [Integration connection](https://cloud.google.com/integration-connectors/docs/overview) + configured to interact with Google Calendar APIs. Follow the + [documentation](https://google.github.io/adk-docs/tools/google-cloud-tools/#use-integration-connectors) + to provision the Integration Connector in Google Cloud. You will need + the `Connection Name`, `Project ID`, and `Location` of your connection. + * Ensure the connection is configured to use Google Calendar (e.g., by + enabling the `google-calendar-connector` or a similar connector). + +2. **Configure OAuth 2.0 Client:** + * You need an OAuth 2.0 Client ID and Client Secret that is authorized to + access the required Google Calendar scopes (e.g., + `https://www.googleapis.com/auth/calendar.readonly`). You can create + OAuth credentials in the Google Cloud Console under "APIs & Services" + -> "Credentials". + +3. **Configure Environment Variables:** + * Create a `.env` file in the same directory as `agent.py` (or add to + your existing one). + * Add the following variables to the `.env` file, replacing the + placeholder values with your actual connection details: + + ```dotenv + CONNECTION_NAME= + CONNECTION_PROJECT= + CONNECTION_LOCATION= + CLIENT_ID= + CLIENT_SECRET= + ``` + +## End-User Authentication (OAuth 2.0) + +This agent utilizes the `AuthCredential` and `OAuth2Auth` classes from the ADK +to handle authentication. +* It defines an OAuth 2.0 scheme (`oauth2_scheme`) based on Google Cloud's + OAuth endpoints and required scopes. +* It uses the `CLIENT_ID` and `CLIENT_SECRET` from the environment variables + (or hardcoded values in the sample) to configure `OAuth2Auth`. +* This `AuthCredential` is passed to the `ApplicationIntegrationToolset`, + enabling the tool to make authenticated API calls to Google Calendar on + behalf of the user running the agent. The ADK framework will typically + handle the OAuth flow (e.g., prompting the user for consent) when the tool + is first invoked. + +## How to Use + +1. **Install Dependencies:** Ensure you have the necessary libraries installed + (e.g., `google-adk`, `python-dotenv`). +2. **Run the Agent:** Execute the agent script from your terminal: + ```bash + python agent.py + ``` +3. **Interact:** Once the agent starts, you can interact with it. If it's the + first time using the tool requiring OAuth, you might be prompted to go + through the OAuth consent flow in your browser. After successful + authentication, you can ask the agent to perform tasks. + +## Sample Prompts + +Here are some examples of how you can interact with the agent: + +* `Can you list events from my primary calendar?` \ No newline at end of file diff --git a/contributing/samples/integration_connector_euc_agent/__init__.py b/contributing/samples/integration_connector_euc_agent/__init__.py new file mode 100644 index 0000000..02c597e --- /dev/null +++ b/contributing/samples/integration_connector_euc_agent/__init__.py @@ -0,0 +1 @@ +from . import agent diff --git a/contributing/samples/integration_connector_euc_agent/agent.py b/contributing/samples/integration_connector_euc_agent/agent.py new file mode 100644 index 0000000..b21a965 --- /dev/null +++ b/contributing/samples/integration_connector_euc_agent/agent.py @@ -0,0 +1,95 @@ +# 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 +from google.adk import Agent +from google.adk.auth import AuthCredential +from google.adk.auth import AuthCredentialTypes +from google.adk.auth import OAuth2Auth +from google.adk.tools.application_integration_tool.application_integration_toolset import ApplicationIntegrationToolset +from google.adk.tools.openapi_tool.auth.auth_helpers import dict_to_auth_scheme +from google.genai import types + +# Load environment variables from .env file +load_dotenv() + +connection_name = os.getenv("CONNECTION_NAME") +connection_project = os.getenv("CONNECTION_PROJECT") +connection_location = os.getenv("CONNECTION_LOCATION") +client_secret = os.getenv("CLIENT_SECRET") +client_id = os.getenv("CLIENT_ID") + + +oauth2_data_google_cloud = { + "type": "oauth2", + "flows": { + "authorizationCode": { + "authorizationUrl": "https://accounts.google.com/o/oauth2/auth", + "tokenUrl": "https://oauth2.googleapis.com/token", + "scopes": { + "https://www.googleapis.com/auth/cloud-platform": ( + "View and manage your data across Google Cloud Platform" + " services" + ), + "https://www.googleapis.com/auth/calendar.readonly": ( + "View your calendars" + ), + }, + } + }, +} + +oauth2_scheme = dict_to_auth_scheme(oauth2_data_google_cloud) + +auth_credential = AuthCredential( + auth_type=AuthCredentialTypes.OAUTH2, + oauth2=OAuth2Auth( + client_id=client_id, + client_secret=client_secret, + ), +) + +calendar_tool = ApplicationIntegrationToolset( + project=connection_project, + location=connection_location, + tool_name_prefix="calendar_tool", + connection=connection_name, + actions=["GET_calendars/%7BcalendarId%7D/events"], + tool_instructions=""" + Use this tool to list events in a calendar. Get calendarId from the user and use it in tool as following example: + connectorInputPayload: { "Path parameters": { "calendarId": "primary" } }. Follow the schema correctly. Note its "Path parameters" and not "Path_parameters". + """, + auth_scheme=oauth2_scheme, + auth_credential=auth_credential, +) + +root_agent = Agent( + model="gemini-2.0-flash", + name="data_processing_agent", + description="Agent that can list events in a calendar.", + instruction=""" + Helps you with calendar related tasks. + """, + tools=calendar_tool.get_tools(), + generate_content_config=types.GenerateContentConfig( + safety_settings=[ + types.SafetySetting( + category=types.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, + threshold=types.HarmBlockThreshold.OFF, + ), + ] + ), +) diff --git a/src/google/adk/tools/application_integration_tool/clients/connections_client.py b/src/google/adk/tools/application_integration_tool/clients/connections_client.py index b56b5cf..8dec389 100644 --- a/src/google/adk/tools/application_integration_tool/clients/connections_client.py +++ b/src/google/adk/tools/application_integration_tool/clients/connections_client.py @@ -728,6 +728,9 @@ class ConnectionsClient: "query": {"$ref": "#/components/schemas/query"}, "timeout": {"$ref": "#/components/schemas/timeout"}, "pageSize": {"$ref": "#/components/schemas/pageSize"}, + "dynamicAuthConfig": { + "$ref": "#/components/schemas/dynamicAuthConfig" + }, }, }