Compare commits

..

68 Commits

Author SHA1 Message Date
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
Xiang (Sean) Zhou 9a1115c504 chore: Remove service account support
given it was not correctly supported.

PiperOrigin-RevId: 773137317
2025-06-18 18:19:05 -07:00
Xiang (Sean) Zhou 913d771d6d chore: Raise meaningful errors when importing a2a modules for python 3.9
PiperOrigin-RevId: 773128206
2025-06-18 17:43:11 -07:00
Hangfei Lin 58e07cae83 fix: Fix tracing for live
the original code passed in wrong args. now fixed.
tested locally.

PiperOrigin-RevId: 773108589
2025-06-18 16:35:16 -07:00
Xiang (Sean) Zhou 157d9be88d feat: Enable MCP Tool Auth (Experimental)
PiperOrigin-RevId: 773002759
2025-06-18 11:44:02 -07:00
Xiang (Sean) Zhou 18a541c8fa chore: Ignore mcp_tool ut tests for python 3.9 given mcp sdk only supports 3.10+
PiperOrigin-RevId: 772999037
2025-06-18 11:34:10 -07:00
Xiang (Sean) Zhou dcea7767c6 feat: Add Authenticated Tool (Experimental)
PiperOrigin-RevId: 772992074
2025-06-18 11:17:01 -07:00
Xiang (Sean) Zhou 2c739ab581 chore: Add Credential Manager for managing tools credential (Experimental)
PiperOrigin-RevId: 772986051
2025-06-18 11:01:38 -07:00
Xiang (Sean) Zhou 9a207cb832 refactor: Refactor oauth2_credential_exchanger to exchanger and refresher separately
PiperOrigin-RevId: 772979993
2025-06-18 10:46:39 -07:00
Xiang (Sean) Zhou a17ebe6ebd chore: Add a credential refresher registry
PiperOrigin-RevId: 772747251
2025-06-17 21:12:30 -07:00
Xiang (Sean) Zhou 55201cb6a1 chore: Add credential exchanger registry (Experimentals)
PiperOrigin-RevId: 772713412
2025-06-17 19:09:21 -07:00
Xiang (Sean) Zhou 0a9625317a refactor: Adapt service account credential exchanger to base credential exchanger interface
PiperOrigin-RevId: 772710438
2025-06-17 18:55:46 -07:00
Google Team Member f9fa7841df chore: add google-adk/{version} to bigquery user agent
PiperOrigin-RevId: 772703504
2025-06-17 18:31:34 -07:00
Xiang (Sean) Zhou 5f89a469ec chore: Add credential service to runner and invocation context
PiperOrigin-RevId: 772697298
2025-06-17 18:08:43 -07:00
Google Team Member 6d174eba30 fix: Set explicit project in the BigQuery client
This change sets an explicit project id in the BigQuery client from the conversation context. Without this the client was trying to set a project from the environment's application default credentials and running into issues where application default credentials is not available.

PiperOrigin-RevId: 772695883
2025-06-17 18:04:41 -07:00
Xiang (Sean) Zhou c04adaade1 chore: Add in memory credential service (Experimental)
PiperOrigin-RevId: 772534962
2025-06-17 10:45:49 -07:00
Google Team Member 1ae176ad2f fix: update conversion between Celsius and Fahrenheit
#non-breaking
The correct conversion from 25 degrees Celsius is 77 degrees Fahrenheit. The previous value of 41 was wrong.

PiperOrigin-RevId: 772528757
2025-06-17 10:31:36 -07:00
SimonWei 694b71256c fix: agent generate config error (#1450) 2025-06-17 08:48:00 -07:00
Xiang (Sean) Zhou e1812797ad chore: Add A2A Part converter (WIP)
PiperOrigin-RevId: 772282116
2025-06-16 20:35:09 -07:00
Xiang (Sean) Zhou c755cf23c5 chore: Ignore a2a ut tests for python 3.9 given a2a-sdk only supports 3.10+
PiperOrigin-RevId: 772270172
2025-06-16 19:53:46 -07:00
Xiang (Sean) Zhou 94caccc148 refactor: Extract util method from OAuth2 credential fetcher for reuse
Context: we'd like to separate fetcher into exchanger and refresher later. This cl help to extract the common utility that will be used by both exchanger and refresher.

PiperOrigin-RevId: 772257995
2025-06-16 19:03:16 -07:00
Xiang (Sean) Zhou 476805d5b9 chore: Add a2a extra dependency for github UT workflows
PiperOrigin-RevId: 772251530
2025-06-16 18:34:18 -07:00
Xiang (Sean) Zhou e2a81365ec chore: Add a base credential refresher interface
PiperOrigin-RevId: 772248299
2025-06-16 18:21:35 -07:00
Xiang (Sean) Zhou 28dfcd2512 chore: Add experimental decorator to Oauth2 credential fethcer
PiperOrigin-RevId: 772236406
2025-06-16 17:36:48 -07:00
Xiang (Sean) Zhou a6b1baa61b chore: Add base credential exchanger (Experimental)
PiperOrigin-RevId: 772227201
2025-06-16 17:05:20 -07:00
Liang Wu e384fa4ad7 chore: fix previously skipped isort issue
PiperOrigin-RevId: 772224853
2025-06-16 16:57:46 -07:00
Google Team Member aafa80bd85 fix: stream in litellm + adk and add corresponding integration tests
Fixes https://github.com/google/adk-python/issues/1368

PiperOrigin-RevId: 772218385
2025-06-16 16:37:14 -07:00
Xiang (Sean) Zhou 4bda245171 chore: fix oauth_calendar_agent example
PiperOrigin-RevId: 772214855
2025-06-16 16:26:59 -07:00
Xiang (Sean) Zhou 31b81a342d chore: Update streamable http mcp example agent
PiperOrigin-RevId: 772213323
2025-06-16 16:22:09 -07:00
Google Team Member fef8778429 fix: liteLLM test failures
Fix liteLLM test failures for function call responses.

PiperOrigin-RevId: 772212629
2025-06-16 16:20:23 -07:00
Hangfei Lin fe1d5aa439 feat: add enable_affective_dialog and proactivity to run_config and llm_request
PiperOrigin-RevId: 772175206
2025-06-16 14:35:47 -07:00
Hangfei Lin 8201f9aebd chore: Added live-streaming sample agent
Also added a readme.

PiperOrigin-RevId: 772120698
2025-06-16 12:07:09 -07:00
Xuan Yang 1cfc555e70 ADK changes
PiperOrigin-RevId: 772078053
2025-06-16 10:20:23 -07:00
SimonWei badbcbd7a4 fix: agent generate config err (#1305)
* fix: agent generate config err

* fix: resovle comment

---------

Co-authored-by: Hangfei Lin <hangfei@google.com>
Co-authored-by: genquan9 <49327371+genquan9@users.noreply.github.com>
2025-06-16 09:40:41 -07:00
Google Team Member 675faefc67 feat: Allow data_store_specs pass into ADK VAIS built-in tool
PiperOrigin-RevId: 772039465
2025-06-16 08:35:30 -07:00
Xiang (Sean) Zhou a4d432a9e6 chore: Add Service Account Credential Exchanger (Experimental)
PiperOrigin-RevId: 771507089
2025-06-14 13:39:50 -07:00
Xiang (Sean) Zhou d1bda9d946 chore: Allow working_in_progress feature for unittests
PiperOrigin-RevId: 771500394
2025-06-14 12:56:02 -07:00
Xiang (Sean) Zhou a19d617ed8 chore: Add experimental decorator to BigQuery tools
PiperOrigin-RevId: 771359886
2025-06-13 23:32:33 -07:00
Xiang (Sean) Zhou 8ebf229c47 chore: Add base credential service interface (WIP)
PiperOrigin-RevId: 771358480
2025-06-13 23:24:30 -07:00
Xiang (Sean) Zhou b51a1f45fd chore: support @working_in_progress and @expremental without calling parameters
PiperOrigin-RevId: 771357728
2025-06-13 23:18:43 -07:00
Xiang (Sean) Zhou 8932106246 chore: Raise error when using features decorated by working_in_progress decorator
set environment variable ADK_ALLOW_WIP_FEATURES=true can bypass it.
working_in_progress features are not working. ADK users are not supposed to set this environment variable.

PiperOrigin-RevId: 771333335
2025-06-13 21:17:31 -07:00
Google Team Member 233fd20243 feat: Add import session API in the fast API
PiperOrigin-RevId: 771279971
2025-06-13 17:26:08 -07:00
Xiang (Sean) Zhou d129fd636b chore: Update the comments of MCPTool
PiperOrigin-RevId: 771234262
2025-06-13 14:53:41 -07:00
Selcuk Gun 131957c531 chore: Triaging agent improvements & github workflow
* modified list issues to only return unlabelled open issues
* added github workflow to run on schedule and issue open/reopen
* interactive/workflow modes
* readme document

PiperOrigin-RevId: 771152306
2025-06-13 10:56:32 -07:00
Google Team Member 8e285874da feat: Add integration tests for litellm with and without turn on add_function_to_prompt
Add experiments for https://github.com/google/adk-python/issues/1273

PiperOrigin-RevId: 771145715
2025-06-13 10:37:09 -07:00
Google Team Member cb55970969 refactor: Simplify agent_tool.py
PiperOrigin-RevId: 771135917
2025-06-13 10:10:31 -07:00
Xiang (Sean) Zhou 40b15ad278 refactor: enhance mcp tool session management
1. remove unnecessary cached session instance in mcp toolset
2. move session reinitialization logic from mcp tool and mcp toolset to mcp session manager
3. add lock for the code block of session creation to avoid race conditions

PiperOrigin-RevId: 770949529
2025-06-12 23:11:06 -07:00
Xiang (Sean) Zhou dbdeb49090 chore: Add a2a-sdk to pyproject.toml
PiperOrigin-RevId: 770908052
2025-06-12 20:30:14 -07:00
Xiang (Sean) Zhou 177980106b feat: Support refresh access token automatically for rest_api_tool
1. let auth_handler.py to utilize the oauth2 credential fetcher to exchange token
2. restructure tool_auth_handler.py to support refresh token

PiperOrigin-RevId: 770901469
2025-06-12 20:07:43 -07:00
Xiang (Sean) Zhou c5b063f1ff feat: Add an Oauth2 credential fetcher to exchange and refresh oauth2 token
PiperOrigin-RevId: 770892243
2025-06-12 19:40:16 -07:00
Google Team Member 313f1b0913 chore: Add all missing direct deps to pyproject.toml
PiperOrigin-RevId: 770887371
2025-06-12 19:21:13 -07:00
Google Team Member b2fc7740b3 fix: Support project-based gemini model path to use google_search_tool
PiperOrigin-RevId: 770858301
2025-06-12 17:30:45 -07:00
Xiang (Sean) Zhou 29e4ca9152 chore: Add empty a2a package
PiperOrigin-RevId: 770851838
2025-06-12 17:07:05 -07:00
Xiang (Sean) Zhou 4ccda99e8e fix: Merge custom http options with adk specific http options in model api request
PiperOrigin-RevId: 770836112
2025-06-12 16:20:31 -07:00
GenkiNoguchi d22920bd7f feat: support realtime input config
Merge https://github.com/google/adk-python/pull/981

issue: https://github.com/google/adk-python/issues/982

This pull request introduces a new configuration option, `realtime_input_config`, to the `RunConfig` class.

**Reason for this change:**

Currently, there is no direct way to configure real-time audio input behaviors, such as Voice Activity Detection (VAD), for live agents through the `RunConfig`. The Gemini API documentation (specifically [Configure automatic VAD](https://ai.google.dev/gemini-api/docs/live#configure-automatic-vad)) outlines parameters for VAD that users may want to customize.

This change enables users to pass these real-time input configurations, providing more granular control over the audio input for live agents.

**Changes made:**

- Added a new optional field `realtime_input_config: Optional[types.RealtimeInputConfig]` to the `RunConfig` class.
- The docstring for `realtime_input_config` has been added to explain its purpose.

**Example Usage (Conceptual):**

While the specific structure of `types.RealtimeInputConfig` would define the exact parameters, a user might configure it like this:

```python
# (Assuming types.RealtimeInputConfig and types.VadConfig are defined elsewhere)
# import your_project.types as types

run_config = RunConfig(
    # ... other configurations ...
    realtime_input_config=types.RealtimeInputConfig(
        automatic_activity_detection =types.AutomaticActivityDetection(
            # VAD specific parameters like sensitivity, endpoint_duration_millis etc.
            # based on https://ai.google.dev/gemini-api/docs/live#configure-automatic-vad
        )
        # Potentially other real-time input settings could be added here in the future
    )
)
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/981 from ammmr:patch-add-realtime-input-config b2e17fbf5742d264029ad49bf632422b5c5b1e0a
PiperOrigin-RevId: 770797640
2025-06-12 14:33:05 -07:00
Google Team Member 2ff9b1f639 test: Add unit tests for execute_sql tool
This change introduces unit tests in which the behavior of the tool is asserted for various query types in various write modes through a mocked BigQuery client.

PiperOrigin-RevId: 770653117
2025-06-12 07:52:41 -07:00
Google Team Member 0a5cf45a75 feat: Implement GcsEvalSetResultsManager to handle storage of eval sets on GCS, and refactor eval set results manager
Eval results will be stored as json files under `gs://{bucket_name}/{app_name}/evals/eval_history/`

PiperOrigin-RevId: 770499242
2025-06-11 23:41:54 -07:00
Google Team Member 1551bd4f4d feat: Re-factor some eval sets manager logic, and implement GcsEvalSetsManager to handle storage of eval sets on GCS
Eval sets will be stored as json files under `gs://{bucket_name}/{app_name}/evals/eval_sets/`

PiperOrigin-RevId: 770487129
2025-06-11 23:02:53 -07:00
Koichi Shiraishi bbceb4f2e8 fix: remove unnecessary double quote on Claude docstring
Merge https://github.com/google/adk-python/pull/1266

Subject says it all.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/1266 from zchee:fix-docstring b5ceacc82b45398e9421c0f9a1a4d6352d12e21a
PiperOrigin-RevId: 770478088
2025-06-11 22:33:07 -07:00
Wei Sun (Jack) b08bdbcd7f chore: Fixes the sample of example_tool
The `Example` objects should be strong typed.

PiperOrigin-RevId: 770476132
2025-06-11 22:27:25 -07:00
Shangjie Chen fc65873d7c chore: Set agent_engine_id in the service constructor, also use the agent_engine_id field instead of overriding app_name in FastAPI endpoint
PiperOrigin-RevId: 770427903
2025-06-11 19:46:25 -07:00
Wei Sun (Jack) a7ea374dfb chore: Update isort config to prevent vscode flickering
PiperOrigin-RevId: 770406033
2025-06-11 18:25:35 -07:00
124 changed files with 11314 additions and 827 deletions
+12 -4
View File
@@ -43,11 +43,19 @@ jobs:
run: |
uv venv .venv
source .venv/bin/activate
uv sync --extra test --extra eval
uv sync --extra test --extra eval --extra a2a
- name: Run unit tests with pytest
run: |
source .venv/bin/activate
pytest tests/unittests \
--ignore=tests/unittests/artifacts/test_artifact_service.py \
--ignore=tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py
if [[ "${{ matrix.python-version }}" == "3.9" ]]; then
pytest tests/unittests \
--ignore=tests/unittests/a2a \
--ignore=tests/unittests/tools/mcp_tool \
--ignore=tests/unittests/artifacts/test_artifact_service.py \
--ignore=tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py
else
pytest tests/unittests \
--ignore=tests/unittests/artifacts/test_artifact_service.py \
--ignore=tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py
fi
+43
View File
@@ -0,0 +1,43 @@
name: ADK Issue Triaging Agent
on:
issues:
types: [opened, reopened]
schedule:
- cron: '0 */6 * * *' # every 6h
jobs:
agent-triage-issues:
runs-on: ubuntu-latest
permissions:
issues: write
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install requests google-adk
- name: Run Triaging Script
env:
GITHUB_TOKEN: ${{ secrets.ADK_TRIAGE_AGENT }}
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
GOOGLE_GENAI_USE_VERTEXAI: 0
OWNER: 'google'
REPO: 'adk-python'
INTERACTIVE: 0
EVENT_NAME: ${{ github.event_name }} # 'issues', 'schedule', etc.
ISSUE_NUMBER: ${{ github.event.issue.number }}
ISSUE_TITLE: ${{ github.event.issue.title }}
ISSUE_BODY: ${{ github.event.issue.body }}
ISSUE_COUNT_TO_PROCESS: '3' # Process 3 issues at a time on schedule
run: python contributing/samples/adk_triaging_agent/main.py
+44
View File
@@ -1,5 +1,49 @@
# Changelog
## [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)
@@ -0,0 +1,67 @@
# ADK Issue Triaging Assistant
The ADK Issue Triaging Assistant is a Python-based agent designed to help manage and triage GitHub issues for the `google/adk-python` repository. It uses a large language model to analyze new and unlabelled issues, recommend appropriate labels based on a predefined set of rules, and apply them.
This agent can be operated in two distinct modes: an interactive mode for local use or as a fully automated GitHub Actions workflow.
---
## Interactive Mode
This mode allows you to run the agent locally to review its recommendations in real-time before any changes are made to your repository's issues.
### Features
* **Web Interface**: The agent's interactive mode can be rendered in a web browser using the ADK's `adk web` command.
* **User Approval**: In interactive mode, the agent is instructed to ask for your confirmation before applying a label to a GitHub issue.
### Running in Interactive Mode
To run the agent in interactive mode, first set the required environment variables. Then, execute the following command in your terminal:
```bash
adk web
```
This will start a local server and provide a URL to access the agent's web interface in your browser.
---
## GitHub Workflow Mode
For automated, hands-off issue triaging, the agent can be integrated directly into your repository's CI/CD pipeline using a GitHub Actions workflow.
### Workflow Triggers
The GitHub workflow is configured to run on specific triggers:
1. **Issue Events**: The workflow executes automatically whenever a new issue is `opened` or an existing one is `reopened`.
2. **Scheduled Runs**: The workflow also runs on a recurring schedule (every 6 hours) to process any unlabelled issues that may have been missed.
### Automated Labeling
When running as part of the GitHub workflow, the agent operates non-interactively. It identifies the best label and applies it directly without requiring user approval. This behavior is configured by setting the `INTERACTIVE` environment variable to `0` in the workflow file.
### Workflow Configuration
The workflow is defined in a YAML file (`.github/workflows/triage.yml`). This file contains the steps to check out the code, set up the Python environment, install dependencies, and run the triaging script with the necessary environment variables and secrets.
---
## Setup and Configuration
Whether running in interactive or workflow mode, the agent requires the following setup.
### Dependencies
The agent requires the following Python libraries.
```bash
pip install --upgrade pip
pip install google-adk requests
```
### Environment Variables
The following environment variables are required for the agent to connect to the necessary services.
* `GITHUB_TOKEN`: **(Required)** A GitHub Personal Access Token with `issues:write` permissions. Needed for both interactive and workflow modes.
* `GOOGLE_API_KEY`: **(Required)** Your API key for the Gemini API. Needed for both interactive and workflow modes.
* `OWNER`: The GitHub organization or username that owns the repository (e.g., `google`). Needed for both modes.
* `REPO`: The name of the GitHub repository (e.g., `adk-python`). Needed for both modes.
* `INTERACTIVE`: Controls the agent's interaction mode. For the automated workflow, this is set to `0`. For interactive mode, it should be set to `1` or left unset.
For local execution in interactive mode, you can place these variables in a `.env` file in the project's root directory. For the GitHub workflow, they should be configured as repository secrets.
+15
View File
@@ -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
@@ -13,61 +13,73 @@
# limitations under the License.
import os
import random
import time
from google.adk import Agent
from google.adk.tools.tool_context import ToolContext
from google.genai import types
import requests
# Read the PAT from the environment variable
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN") # Ensure you've set this in your shell
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
if not GITHUB_TOKEN:
raise ValueError("GITHUB_TOKEN environment variable not set")
# Repository information
OWNER = "google"
REPO = "adk-python"
OWNER = os.getenv("OWNER", "google")
REPO = os.getenv("REPO", "adk-python")
BOT_LABEL = os.getenv("BOT_LABEL", "bot_triaged")
# Base URL for the GitHub API
BASE_URL = "https://api.github.com"
# Headers including the Authorization header
headers = {
"Authorization": f"token {GITHUB_TOKEN}",
"Accept": "application/vnd.github.v3+json",
}
ALLOWED_LABELS = [
"documentation",
"services",
"question",
"tools",
"eval",
"live",
"models",
"tracing",
"core",
"web",
]
def list_issues(per_page: int):
def is_interactive():
return os.environ.get("INTERACTIVE", "1").lower() in ["true", "1"]
def list_issues(issue_count: int):
"""
Generator to list all issues for the repository by handling pagination.
Args:
per_page: number of pages to return per page.
issue_count: number of issues to return
"""
state = "open"
# only process the 1st page for testing for now
page = 1
results = []
url = ( # :contentReference[oaicite:16]{index=16}
f"{BASE_URL}/repos/{OWNER}/{REPO}/issues"
)
# Warning: let's only handle max 10 issues at a time to avoid bad results
params = {"state": state, "per_page": per_page, "page": page}
response = requests.get(url, headers=headers, params=params)
response.raise_for_status() # :contentReference[oaicite:17]{index=17}
issues = response.json()
query = f"repo:{OWNER}/{REPO} is:open is:issue no:label"
unlabelled_issues = []
url = f"{BASE_URL}/search/issues"
params = {
"q": query,
"sort": "created",
"order": "desc",
"per_page": issue_count,
"page": 1,
}
response = requests.get(url, headers=headers, params=params, timeout=60)
response.raise_for_status()
json_response = response.json()
issues = json_response.get("items", None)
if not issues:
return []
for issue in issues:
# Skip pull requests (issues API returns PRs as well)
if "pull_request" in issue:
continue
results.append(issue)
return results
if not issue.get("labels", None) or len(issue["labels"]) == 0:
unlabelled_issues.append(issue)
return unlabelled_issues
def add_label_to_issue(issue_number: str, label: str):
@@ -78,41 +90,56 @@ def add_label_to_issue(issue_number: str, label: str):
issue_number: issue number of the Github issue, in string foramt.
label: label to assign
"""
print(f"Attempting to add label '{label}' to issue #{issue_number}")
if label not in ALLOWED_LABELS:
error_message = (
f"Error: Label '{label}' is not an allowed label. Will not apply."
)
print(error_message)
return {"status": "error", "message": error_message, "applied_label": None}
url = f"{BASE_URL}/repos/{OWNER}/{REPO}/issues/{issue_number}/labels"
payload = [label]
response = requests.post(url, headers=headers, json=payload)
payload = [label, BOT_LABEL]
response = requests.post(url, headers=headers, json=payload, timeout=60)
response.raise_for_status()
return response.json()
approval_instruction = (
"Only label them when the user approves the labeling!"
if is_interactive()
else (
"Do not ask for user approval for labeling! If you can't find a"
" appropriate labels for the issue, do not label it."
)
)
root_agent = Agent(
model="gemini-2.5-pro-preview-05-06",
name="adk_triaging_assistant",
description="Triage ADK issues.",
instruction="""
You are a Github adk-python repo triaging bot. You will help get issues, and label them.
instruction=f"""
You are a Github adk-python repo triaging bot. You will help get issues, and recommend a label.
IMPORTANT: {approval_instruction}
Here are the rules for labeling:
- If the user is asking about documentation-related questions, label it with "documentation".
- If it's about session, memory services, label it with "services"
- If it's about UI/web, label it with "question"
- If it's about UI/web, label it with "web"
- If the user is asking about a question, label it with "question"
- If it's related to tools, label it with "tools"
- If it's about agent evalaution, then label it with "eval".
- If it's about streaming/live, label it with "live".
- If it's about model support(non-Gemini, like Litellm, Ollama, OpenAI models), label it with "models".
- If it's about tracing, label it with "tracing".
- If it's agent orchestration, agent definition, label it with "core".
- If you can't find a appropriate labels for the issue, return the issues to user to decide.
- If you can't find a appropriate labels for the issue, follow the previous instruction that starts with "IMPORTANT:".
Present the followings in an easy to read format highlighting issue number and your label.
- the issue summary in a few sentence
- your label recommendation and justification
""",
tools=[
list_issues,
add_label_to_issue,
],
generate_content_config=types.GenerateContentConfig(
safety_settings=[
types.SafetySetting( # avoid false alarm about rolling dice.
category=types.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
threshold=types.HarmBlockThreshold.OFF,
),
]
),
)
@@ -0,0 +1,164 @@
# 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 os
import time
import agent
from dotenv import load_dotenv
from google.adk.agents.run_config import RunConfig
from google.adk.runners import InMemoryRunner
from google.adk.sessions import Session
from google.genai import types
import requests
load_dotenv(override=True)
OWNER = os.getenv("OWNER", "google")
REPO = os.getenv("REPO", "adk-python")
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
BASE_URL = "https://api.github.com"
headers = {
"Authorization": f"token {GITHUB_TOKEN}",
"Accept": "application/vnd.github.v3+json",
}
if not GITHUB_TOKEN:
print(
"Warning: GITHUB_TOKEN environment variable not set. API calls might"
" fail."
)
async def fetch_specific_issue_details(issue_number: int):
"""Fetches details for a single issue if it's unlabelled."""
if not GITHUB_TOKEN:
print("Cannot fetch issue details: GITHUB_TOKEN is not set.")
return None
url = f"{BASE_URL}/repos/{OWNER}/{REPO}/issues/{issue_number}"
print(f"Fetching details for specific issue: {url}")
try:
response = requests.get(url, headers=headers, timeout=60)
response.raise_for_status()
issue_data = response.json()
if not issue_data.get("labels") or len(issue_data["labels"]) == 0:
print(f"Issue #{issue_number} is unlabelled. Proceeding.")
return {
"number": issue_data["number"],
"title": issue_data["title"],
"body": issue_data.get("body", ""),
}
else:
print(f"Issue #{issue_number} is already labelled. Skipping.")
return None
except requests.exceptions.RequestException as e:
print(f"Error fetching issue #{issue_number}: {e}")
if hasattr(e, "response") and e.response is not None:
print(f"Response content: {e.response.text}")
return None
async def main():
app_name = "triage_app"
user_id_1 = "triage_user"
runner = InMemoryRunner(
agent=agent.root_agent,
app_name=app_name,
)
session_11 = await runner.session_service.create_session(
app_name=app_name, user_id=user_id_1
)
async def run_agent_prompt(session: Session, prompt_text: str):
content = types.Content(
role="user", parts=[types.Part.from_text(text=prompt_text)]
)
print(f"\n>>>> Agent Prompt: {prompt_text}")
final_agent_response_parts = []
async for event in runner.run_async(
user_id=user_id_1,
session_id=session.id,
new_message=content,
run_config=RunConfig(save_input_blobs_as_artifacts=False),
):
if event.content.parts and event.content.parts[0].text:
print(f"** {event.author} (ADK): {event.content.parts[0].text}")
if event.author == agent.root_agent.name:
final_agent_response_parts.append(event.content.parts[0].text)
print(f"<<<< Agent Final Output: {''.join(final_agent_response_parts)}\n")
event_name = os.getenv("EVENT_NAME")
issue_number_str = os.getenv("ISSUE_NUMBER")
if event_name == "issues" and issue_number_str:
print(f"EVENT: Processing specific issue due to '{event_name}' event.")
try:
issue_number = int(issue_number_str)
specific_issue = await fetch_specific_issue_details(issue_number)
if specific_issue:
prompt = (
f"A new GitHub issue #{specific_issue['number']} has been opened or"
f" reopened. Title: \"{specific_issue['title']}\"\nBody:"
f" \"{specific_issue['body']}\"\n\nBased on the rules, recommend an"
" appropriate label and its justification."
" Then, use the 'add_label_to_issue' tool to apply the label "
"directly to this issue."
f" The issue number is {specific_issue['number']}."
)
await run_agent_prompt(session_11, prompt)
else:
print(
f"No unlabelled issue details found for #{issue_number} or an error"
" occurred. Skipping agent interaction."
)
except ValueError:
print(f"Error: Invalid ISSUE_NUMBER received: {issue_number_str}")
else:
print(f"EVENT: Processing batch of issues (event: {event_name}).")
issue_count_str = os.getenv("ISSUE_COUNT_TO_PROCESS", "3")
try:
num_issues_to_process = int(issue_count_str)
except ValueError:
print(f"Warning: Invalid ISSUE_COUNT_TO_PROCESS. Defaulting to 3.")
num_issues_to_process = 3
prompt = (
f"List the first {num_issues_to_process} unlabelled open issues from"
f" the {OWNER}/{REPO} repository. For each issue, provide a summary,"
" recommend a label with justification, and then use the"
" 'add_label_to_issue' tool to apply the recommended label directly."
)
await run_agent_prompt(session_11, prompt)
if __name__ == "__main__":
start_time = time.time()
print(
"Script start time:",
time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(start_time)),
)
print("------------------------------------")
asyncio.run(main())
end_time = time.time()
print("------------------------------------")
print(
"Script end time:",
time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(end_time)),
)
print("Total script execution time:", f"{end_time - start_time:.2f} seconds")
+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
+19 -8
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
+42 -37
View File
@@ -15,6 +15,7 @@
import random
from google.adk.agents import Agent
from google.adk.examples.example import Example
from google.adk.tools.example_tool import ExampleTool
from google.genai import types
@@ -66,43 +67,47 @@ def check_prime(nums: list[int]) -> str:
)
example_tool = ExampleTool([
{
"input": {
"role": "user",
"parts": [{"text": "Roll a 6-sided die."}],
},
"output": [
{"role": "model", "parts": [{"text": "I rolled a 4 for you."}]}
],
},
{
"input": {
"role": "user",
"parts": [{"text": "Is 7 a prime number?"}],
},
"output": [{
"role": "model",
"parts": [{"text": "Yes, 7 is a prime number."}],
}],
},
{
"input": {
"role": "user",
"parts": [{"text": "Roll a 10-sided die and check if it's prime."}],
},
"output": [
{
"role": "model",
"parts": [{"text": "I rolled an 8 for you."}],
},
{
"role": "model",
"parts": [{"text": "8 is not a prime number."}],
},
],
},
])
example_tool = ExampleTool(
examples=[
Example(
input=types.UserContent(
parts=[types.Part(text="Roll a 6-sided die.")]
),
output=[
types.ModelContent(
parts=[types.Part(text="I rolled a 4 for you.")]
)
],
),
Example(
input=types.UserContent(
parts=[types.Part(text="Is 7 a prime number?")]
),
output=[
types.ModelContent(
parts=[types.Part(text="Yes, 7 is a prime number.")]
)
],
),
Example(
input=types.UserContent(
parts=[
types.Part(
text="Roll a 10-sided die and check if it's prime."
)
]
),
output=[
types.ModelContent(
parts=[types.Part(text="I rolled an 8 for you.")]
),
types.ModelContent(
parts=[types.Part(text="8 is not a prime number.")]
),
],
),
]
)
prime_agent = Agent(
name="prime_agent",
+15
View File
@@ -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
+104
View File
@@ -0,0 +1,104 @@
# 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.tools.tool_context import ToolContext
from google.genai import types
def roll_die(sides: int, tool_context: ToolContext) -> 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.
"""
result = random.randint(1, sides)
if not 'rolls' in tool_context.state:
tool_context.state['rolls'] = []
tool_context.state['rolls'] = tool_context.state['rolls'] + [result]
return result
async def check_prime(nums: list[int]) -> str:
"""Check if a given list of numbers are prime.
Args:
nums: The list of numbers to check.
Returns:
A str indicating which number is prime.
"""
primes = set()
for number in nums:
number = int(number)
if number <= 1:
continue
is_prime = True
for i in range(2, int(number**0.5) + 1):
if number % i == 0:
is_prime = False
break
if is_prime:
primes.add(number)
return (
'No prime numbers found.'
if not primes
else f"{', '.join(str(num) for num in primes)} are prime numbers."
)
root_agent = Agent(
model='gemini-2.0-flash-live-preview-04-09', # for Vertex project
# model='gemini-2.0-flash-live-001', # for AI studio key
name='hello_world_agent',
description=(
'hello world agent that can roll a dice of 8 sides and check prime'
' numbers.'
),
instruction="""
You roll dice and answer questions about the outcome of the dice rolls.
You can roll dice of different sizes.
You can use multiple tools in parallel by calling functions in parallel(in one request and in one round).
It is ok to discuss previous dice roles, and comment on the dice rolls.
When you are asked to roll a die, you must call the roll_die tool with the number of sides. Be sure to pass in an integer. Do not pass in a string.
You should never roll a die on your own.
When checking prime numbers, call the check_prime tool with a list of integers. Be sure to pass in a list of integers. You should never pass in a string.
You should not check prime numbers before calling the tool.
When you are asked to roll a die and check prime numbers, you should always make the following two function calls:
1. You should first call the roll_die tool to get a roll. Wait for the function response before calling the check_prime tool.
2. After you get the function response from roll_die tool, you should call the check_prime tool with the roll_die result.
2.1 If user asks you to check primes based on previous rolls, make sure you include the previous rolls in the list.
3. When you respond, you must include the roll_die result from step 1.
You should always perform the previous 3 steps when asking for a roll and checking prime numbers.
You should not rely on the previous history on prime results.
""",
tools=[
roll_die,
check_prime,
],
generate_content_config=types.GenerateContentConfig(
safety_settings=[
types.SafetySetting( # avoid false alarm about rolling dice.
category=types.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
threshold=types.HarmBlockThreshold.OFF,
),
]
),
)
@@ -0,0 +1,37 @@
# Simplistic Live (Bidi-Streaming) Agent
This project provides a basic example of a live, bidirectional streaming agent
designed for testing and experimentation.
You can see full documentation [here](https://google.github.io/adk-docs/streaming/).
## Getting Started
Follow these steps to get the agent up and running:
1. **Start the ADK Web Server**
Open your terminal, navigate to the root directory that contains the
`live_bidi_streaming_agent` folder, and execute the following command:
```bash
adk web
```
2. **Access the ADK Web UI**
Once the server is running, open your web browser and navigate to the URL
provided in the terminal (it will typically be `http://localhost:8000`).
3. **Select the Agent**
In the top-left corner of the ADK Web UI, use the dropdown menu to select
this agent.
4. **Start Streaming**
Click on either the **Audio** or **Video** icon located near the chat input
box to begin the streaming session.
5. **Interact with the Agent**
You can now begin talking to the agent, and it will respond in real-time.
## Usage Notes
* You only need to click the **Audio** or **Video** button once to initiate the
stream. The current version does not support stopping and restarting the stream
by clicking the button again during a session.
+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'},
),
@@ -1,8 +1,7 @@
This agent connects to a local MCP server via sse.
This agent connects to a local MCP server via Streamable HTTP.
To run this agent, start the local MCP server first by :
```bash
uv run filesystem_server.py
```
@@ -18,7 +18,6 @@ import os
from google.adk.agents.llm_agent import LlmAgent
from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPServerParams
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__))
+1 -1
View File
@@ -29,7 +29,7 @@ def get_weather(city: str) -> dict:
"status": "success",
"report": (
"The weather in New York is sunny with a temperature of 25 degrees"
" Celsius (41 degrees Fahrenheit)."
" Celsius (77 degrees Fahrenheit)."
),
}
else:
+36 -19
View File
@@ -25,27 +25,32 @@ classifiers = [ # List of https://pypi.org/classifiers/
]
dependencies = [
# go/keep-sorted start
"authlib>=1.5.1", # For RestAPI Tool
"click>=8.1.8", # For CLI tools
"fastapi>=0.115.0", # FastAPI framework
"google-api-python-client>=2.157.0", # Google API client discovery
"google-cloud-aiplatform[agent_engines]>=1.95.1", # For VertexAI integrations, e.g. example store.
"google-cloud-secret-manager>=2.22.0", # Fetching secrets in RestAPI Tool
"google-cloud-speech>=2.30.0", # For Audio Transcription
"google-cloud-storage>=2.18.0, <3.0.0", # For GCS Artifact service
"google-genai>=1.17.0", # Google GenAI SDK
"graphviz>=0.20.2", # Graphviz for graph rendering
"mcp>=1.8.0;python_version>='3.10'", # For MCP Toolset
"opentelemetry-api>=1.31.0", # OpenTelemetry
"anyio>=4.9.0;python_version>='3.10'", # For MCP Session Manager
"authlib>=1.5.1", # For RestAPI Tool
"click>=8.1.8", # For CLI tools
"fastapi>=0.115.0", # FastAPI framework
"google-api-python-client>=2.157.0", # Google API client discovery
"google-cloud-aiplatform[agent_engines]>=1.95.1", # For VertexAI integrations, e.g. example store.
"google-cloud-secret-manager>=2.22.0", # Fetching secrets in RestAPI Tool
"google-cloud-speech>=2.30.0", # For Audio Transcription
"google-cloud-storage>=2.18.0, <3.0.0", # For GCS Artifact service
"google-genai>=1.17.0", # Google GenAI SDK
"graphviz>=0.20.2", # Graphviz for graph rendering
"mcp>=1.8.0;python_version>='3.10'", # For MCP Toolset
"opentelemetry-api>=1.31.0", # OpenTelemetry
"opentelemetry-exporter-gcp-trace>=1.9.0",
"opentelemetry-sdk>=1.31.0",
"pydantic>=2.0, <3.0.0", # For data validation/models
"python-dotenv>=1.0.0", # To manage environment variables
"PyYAML>=6.0.2", # For APIHubToolset.
"sqlalchemy>=2.0", # SQL database ORM
"tzlocal>=5.3", # Time zone utilities
"pydantic>=2.0, <3.0.0", # For data validation/models
"python-dateutil>=2.9.0.post0", # For Vertext AI Session Service
"python-dotenv>=1.0.0", # To manage environment variables
"PyYAML>=6.0.2", # For APIHubToolset.
"requests>=2.32.4",
"sqlalchemy>=2.0", # SQL database ORM
"starlette>=0.46.2", # For FastAPI CLI
"typing-extensions>=4.5, <5",
"uvicorn>=0.34.0", # ASGI server for FastAPI
"tzlocal>=5.3", # Time zone utilities
"uvicorn>=0.34.0", # ASGI server for FastAPI
"websockets>=15.0.1", # For BaseLlmFlow
# go/keep-sorted end
]
dynamic = ["version"]
@@ -71,6 +76,12 @@ dev = [
# go/keep-sorted end
]
a2a = [
# go/keep-sorted start
"a2a-sdk>=0.2.7;python_version>='3.10'"
# go/keep-sorted end
]
eval = [
# go/keep-sorted start
"google-cloud-aiplatform[evaluation]>=1.87.0",
@@ -84,7 +95,7 @@ test = [
"anthropic>=0.43.0", # For anthropic model tests
"langchain-community>=0.3.17",
"langgraph>=0.2.60", # For LangGraphAgent
"litellm>=1.71.2", # For LiteLLM tests
"litellm>=1.71.2", # For LiteLLM tests
"llama-index-readers-file>=0.4.0", # For retrieval tests
"pytest-asyncio>=0.25.0",
@@ -140,24 +151,30 @@ pyink-annotation-pragmas = [
requires = ["flit_core >=3.8,<4"]
build-backend = "flit_core.buildapi"
[tool.flit.sdist]
include = ['src/**/*', 'README.md', 'pyproject.toml', 'LICENSE']
exclude = ['src/**/*.sh']
[tool.flit.module]
name = "google.adk"
include = ["py.typed"]
[tool.isort]
profile = "google"
single_line_exclusions = []
line_length = 200 # Prevent line wrap flickering.
known_third_party = ["google.adk"]
[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_default_fixture_loop_scope = "function"
asyncio_mode = "auto"
[tool.mypy]
python_version = "3.9"
exclude = "tests/"
+13
View File
@@ -0,0 +1,13 @@
# 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.
+13
View File
@@ -0,0 +1,13 @@
# 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.

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