Compare commits

..

8 Commits

Author SHA1 Message Date
Xuan Yang b8644ef32c Make additional_headers kwargs 2025-10-21 12:44:50 -07:00
Xuan Yang ace3e5a3a5 Merge branch 'main' into feature/google-api-toolset-additional-headers-3105 2025-10-20 09:58:15 -07:00
Xuan Yang 37179a6e1f Format conditional statement for setting headers 2025-10-20 09:36:25 -07:00
Parham Alizadeh d8ded07eb3 addressing comments - tidy ups 2025-10-20 10:18:27 +01:00
Parham MohammadAlizadeh a09dd4d31f Merge branch 'main' into feature/google-api-toolset-additional-headers-3105 2025-10-18 12:09:45 +01:00
Parham MohammadAlizadeh 71999b0ef7 Merge branch 'main' into feature/google-api-toolset-additional-headers-3105 2025-10-17 16:37:23 +01:00
Parham MohammadAlizadeh 3d6d6132cd Merge branch 'main' into feature/google-api-toolset-additional-headers-3105 2025-10-17 16:23:25 +01:00
Parham Alizadeh 78e4d81579 feat(tools): support additional headers for google api toolset #non-breaking 2025-10-17 16:22:55 +01:00
348 changed files with 5830 additions and 24361 deletions
-52
View File
@@ -1,52 +0,0 @@
**Please ensure you have read the [contribution guide](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) before creating a pull request.**
### Link to Issue or Description of Change
**1. Link to an existing issue (if applicable):**
- Closes: #_issue_number_
- Related: #_issue_number_
**2. Or, if no issue exists, describe the change:**
_If applicable, please follow the issue templates to provide as much detail as
possible._
**Problem:**
_A clear and concise description of what the problem is._
**Solution:**
_A clear and concise description of what you want to happen and why you choose
this solution._
### Testing Plan
_Please describe the tests that you ran to verify your changes. This is required
for all PRs that are not small documentation or typo fixes._
**Unit Tests:**
- [ ] I have added or updated unit tests for my change.
- [ ] All unit tests pass locally.
_Please include a summary of passed `pytest` results._
**Manual End-to-End (E2E) Tests:**
_Please provide instructions on how to manually test your changes, including any
necessary setup or configuration. Please provide logs or screenshots to help
reviewers better understand the fix._
### Checklist
- [ ] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [ ] I have performed a self-review of my own code.
- [ ] I have commented my code, particularly in hard-to-understand areas.
- [ ] I have added tests that prove my fix is effective or that my feature works.
- [ ] New and existing unit tests pass locally with my changes.
- [ ] I have manually tested my changes end-to-end.
- [ ] Any dependent changes have been merged and published in downstream modules.
### Additional context
_Add any other context or screenshots about the feature request here._
+1 -1
View File
@@ -89,7 +89,7 @@ jobs:
- name: Check for import from cli package in certain changed Python files
run: |
git fetch origin ${{ github.base_ref }}
CHANGED_FILES=$(git diff --diff-filter=ACMR --name-only origin/${{ github.base_ref }}...HEAD | grep -E '\.py$' | grep -v -E 'cli/.*|src/google/adk/tools/apihub_tool/apihub_toolset.py|tests/.*|contributing/samples/' || true)
CHANGED_FILES=$(git diff --diff-filter=ACMR --name-only origin/${{ github.base_ref }}...HEAD | grep -E '\.py$' | grep -v -E 'cli/.*|tests/.*|contributing/samples/' || true)
if [ -n "$CHANGED_FILES" ]; then
echo "Changed Python files to check:"
echo "$CHANGED_FILES"
-134
View File
@@ -1,134 +0,0 @@
name: Copybara PR Handler
on:
push:
branches:
- main
workflow_dispatch:
inputs:
pr_number:
description: 'PR number to close (for testing)'
required: true
type: string
commit_sha:
description: 'Commit SHA reference (optional, for testing)'
required: false
type: string
jobs:
close-imported-pr:
runs-on: ubuntu-latest
permissions:
pull-requests: write
issues: write
contents: read
steps:
- name: Check for Copybara commits and close PRs
uses: actions/github-script@v7
with:
github-token: ${{ secrets.ADK_TRIAGE_AGENT }}
script: |
// Check if this is a manual test run
const isManualRun = context.eventName === 'workflow_dispatch';
let prsToClose = [];
if (isManualRun) {
// Manual testing mode
const prNumber = parseInt(context.payload.inputs.pr_number);
const commitSha = context.payload.inputs.commit_sha || context.sha.substring(0, 7);
console.log('=== MANUAL TEST MODE ===');
console.log(`Testing with PR #${prNumber}, commit ${commitSha}`);
prsToClose.push({ prNumber, commitSha });
} else {
// Normal mode: process commits from push event
const commits = context.payload.commits || [];
console.log(`Found ${commits.length} commit(s) in this push`);
// Process each commit
for (const commit of commits) {
const sha = commit.id;
const committer = commit.committer.name;
const message = commit.message;
console.log(`\n--- Processing commit ${sha.substring(0, 7)} ---`);
console.log(`Committer: ${committer}`);
// Check if this is a Copybara commit
if (committer !== 'Copybara-Service') {
console.log('Not a Copybara commit, skipping');
continue;
}
// Extract PR number from commit message
// Pattern: "Merge https://github.com/google/adk-python/pull/3333"
const prMatch = message.match(/Merge https:\/\/github\.com\/google\/adk-python\/pull\/(\d+)/);
if (!prMatch) {
console.log('No PR number found in Copybara commit message');
continue;
}
const prNumber = parseInt(prMatch[1]);
const commitSha = sha.substring(0, 7);
prsToClose.push({ prNumber, commitSha });
}
}
// Process PRs to close
for (const { prNumber, commitSha } of prsToClose) {
console.log(`\n--- Processing PR #${prNumber} ---`);
// Get PR details to check if it's open
let pr;
try {
pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
} catch (error) {
console.log(`PR #${prNumber} not found or inaccessible:`, error.message);
continue;
}
// Only close if PR is still open
if (pr.data.state !== 'open') {
console.log(`PR #${prNumber} is already ${pr.data.state}, skipping`);
continue;
}
const author = pr.data.user.login;
try {
// Add comment with commit reference
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: `Thank you @${author} for your contribution! 🎉\n\nYour changes have been successfully imported and merged via Copybara in commit ${commitSha}.\n\nClosing this PR as the changes are now in the main branch.`
});
// Close the PR
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber,
state: 'closed'
});
console.log(`Successfully closed PR #${prNumber}`);
} catch (error) {
console.log(`Error closing PR #${prNumber}:`, error.message);
}
}
if (isManualRun) {
console.log('\n=== TEST COMPLETED ===');
} else {
console.log('\n--- Finished processing all commits ---');
}
-17
View File
@@ -98,20 +98,3 @@ Thumbs.db
*.bak
*.tmp
*.temp
# AI Coding Tools - Project-specific configs
# Developers should symlink or copy AGENTS.md and add their own overrides locally
.claude/
CLAUDE.md
.cursor/
.cursorrules
.cursorignore
.windsurfrules
.aider*
.continue/
.codeium/
.githubnext/
.roo/
.rooignore
.bolt/
.v0/
+40 -299
View File
@@ -1,59 +1,15 @@
# AI Coding Assistant Context
# Gemini CLI / Gemini Code Assist Context
This document provides context for AI coding assistants (Claude Code, Gemini CLI, GitHub Copilot, Cursor, etc.) to understand the ADK Python project and assist with development.
This document provides context for the Gemini CLI and Gemini Code Assist to understand the project and assist with development.
## Project Overview
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.
### Key Components
- **Agent** - Blueprint defining identity, instructions, and tools (`LlmAgent`, `LoopAgent`, `ParallelAgent`, `SequentialAgent`, etc.)
- **Runner** - Execution engine that orchestrates the "Reason-Act" loop, manages LLM calls, executes tools, and handles multi-agent coordination
- **Tool** - Functions/capabilities agents can call (Python functions, OpenAPI specs, MCP tools, Google API tools)
- **Session** - Conversation state management (in-memory, Vertex AI, Spanner-backed)
- **Memory** - Long-term recall across sessions
## Project Architecture
Please refer to [ADK Project Overview and Architecture](https://github.com/google/adk-python/blob/main/contributing/adk_project_overview_and_architecture.md) for details.
### Source Structure
```
src/google/adk/
├── agents/ # Agent implementations (LlmAgent, LoopAgent, ParallelAgent, etc.)
├── runners.py # Core Runner orchestration class
├── tools/ # Tool ecosystem (50+ files)
│ ├── google_api_tool/
│ ├── bigtable/, bigquery/, spanner/
│ ├── openapi_tool/
│ └── mcp_tool/ # Model Context Protocol
├── models/ # LLM integrations (Gemini, Anthropic, LiteLLM)
├── sessions/ # Session management (in-memory, Vertex AI, Spanner)
├── memory/ # Long-term memory services
├── evaluation/ # Evaluation framework (47 files)
├── cli/ # CLI tools and web UI
├── flows/ # Execution flow orchestration
├── a2a/ # Agent-to-Agent protocol
├── telemetry/ # Observability and tracing
└── utils/ # Utility functions
```
### Test Structure
```
tests/
├── unittests/ # 2600+ unit tests across 236+ files
│ ├── agents/
│ ├── tools/
│ ├── models/
│ ├── evaluation/
│ ├── a2a/
│ └── ...
└── integration/ # Integration tests
```
### ADK Live (Bidi-streaming)
- ADK live feature can be accessed from runner.run_live(...) and corresponding FAST api endpoint.
@@ -65,128 +21,6 @@ tests/
- User audio or model audio should be saved into artifacts with a reference in Event to it.
- Tests are in [tests/unittests/streaming](https://github.com/google/adk-python/tree/main/tests/unittests/streaming).
### Agent Structure Convention (Required)
**All agent directories must follow this structure:**
```
my_agent/
├── __init__.py # MUST contain: from . import agent
└── agent.py # MUST define: root_agent = Agent(...) OR app = App(...)
```
**Choose one pattern based on your needs:**
**Option 1 - Simple Agent (for basic agents without plugins):**
```python
from google.adk.agents import Agent
from google.adk.tools import google_search
root_agent = Agent(
name="search_assistant",
model="gemini-2.5-flash",
instruction="You are a helpful assistant.",
description="An assistant that can search the web.",
tools=[google_search]
)
```
**Option 2 - App Pattern (when you need plugins, event compaction, custom configuration):**
```python
from google.adk import Agent
from google.adk.apps import App
from google.adk.plugins import ContextFilterPlugin
root_agent = Agent(
name="my_agent",
model="gemini-2.5-flash",
instruction="You are a helpful assistant.",
tools=[...],
)
app = App(
name="my_app",
root_agent=root_agent,
plugins=[
ContextFilterPlugin(num_invocations_to_keep=3),
],
)
```
**Rationale:** This structure allows the ADK CLI (`adk web`, `adk run`, etc.) to automatically discover and load agents without additional configuration.
## Development Setup
### Requirements
**Minimum requirements:**
- Python 3.9+ (**Python 3.11+ strongly recommended** for best performance)
- `uv` package manager (**required** - faster than pip/venv)
**Install uv if not already installed:**
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```
### Setup Instructions
**Standard setup for development:**
```bash
# Create virtual environment with Python 3.11
uv venv --python "python3.11" ".venv"
source .venv/bin/activate
# Install all dependencies for development
uv sync --all-extras
```
**Minimal setup for testing only (matches CI):**
```bash
uv sync --extra test --extra eval --extra a2a
```
**Virtual Environment Usage (Required):**
- **Always use** `.venv/bin/python` or `.venv/bin/pytest` directly
- **Or activate** with `source .venv/bin/activate` before running commands
- **Never use** `python -m venv` - always create with `uv venv` if missing
**Rationale:** `uv` is significantly faster and ensures consistent dependency resolution across the team.
### Building
```bash
# Build wheel
uv build
# Install local build for testing
pip install dist/google_adk-<version>-py3-none-any.whl
```
### Running Agents Locally
**For interactive development and debugging:**
```bash
# Launch web UI (recommended for development)
adk web path/to/agents_dir
```
**For CLI-based testing:**
```bash
# Interactive CLI (prompts for user input)
adk run path/to/my_agent
```
**For API/production mode:**
```bash
# Start FastAPI server
adk api_server path/to/agents_dir
```
**For running evaluations:**
```bash
# Run evaluation set against agent
adk eval path/to/my_agent path/to/eval_set.json
```
## ADK: Style Guides
### Python Style Guide
@@ -203,68 +37,48 @@ The project follows the Google Python Style Guide. Key conventions are enforced
* **Imports**: Organized and sorted.
* **Error Handling**: Specific exceptions should be caught, not general ones like `Exception`.
### Autoformat (Required Before Committing)
### Autoformat
We have autoformat.sh to help solve import organize and formatting issues.
**Always run** before committing code:
```bash
./autoformat.sh
# Run in open_source_workspace/
$ ./autoformat.sh
```
**Manual formatting** (if needed):
```bash
# Format imports
isort src/ tests/ contributing/
# Format code style
pyink --config pyproject.toml src/ tests/ contributing/
```
**Check formatting** without making changes:
```bash
pyink --check --diff --config pyproject.toml src/
isort --check src/
```
**Formatting Standards (Enforced by CI):**
- **Formatter:** `pyink` (Google-style Python formatter)
- **Line length:** 80 characters maximum
- **Indentation:** 2 spaces (never tabs)
- **Import sorter:** `isort` with Google profile
- **Linter:** `pylint` with Google Python Style Guide
**Rationale:** Consistent formatting eliminates style debates and makes code reviews focus on logic rather than style.
### In ADK source
Below styles applies to the ADK source code (under `src/` folder of the GitHub repo).
Below styles applies to the ADK source code (under `src/` folder of the Github.
repo).
#### Use relative imports (Required)
#### Use relative imports
```python
# DO - Use relative imports
# DO
from ..agents.llm_agent import LlmAgent
# DON'T - No absolute imports
# DON'T
from google.adk.agents.llm_agent import LlmAgent
```
**Rationale:** Relative imports make the code more maintainable and avoid circular import issues in large codebases.
#### Import from module, not from `__init__.py` (Required)
#### Import from module, not from `__init__.py`
```python
# DO - Import directly from module
# DO
from ..agents.llm_agent import LlmAgent
# DON'T - Import from __init__.py
from ..agents import LlmAgent
# DON'T
from ..agents import LlmAgent # import from agents/__init__.py
```
**Rationale:** Direct module imports make dependencies explicit and improve IDE navigation and refactoring.
#### Always do `from __future__ import annotations`
#### Always do `from __future__ import annotations` (Required)
```python
# DO THIS, right after the open-source header.
from __future__ import annotations
```
**Rule:** Every source file must include `from __future__ import annotations` immediately after the license header, before any other imports.
Like below:
```python
# Copyright 2025 Google LLC
@@ -281,72 +95,39 @@ from ..agents import LlmAgent
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations # REQUIRED - Always include this
from __future__ import annotations
# ... rest of imports ...
# ... the rest of the file.
```
**Rationale:** This enables forward-referencing classes without quotes, improving code readability and type hint support (PEP 563).
This allows us to forward-reference a class without quotes.
Check out go/pep563 for details.
### In ADK tests
#### Use absolute imports (Required)
#### Use absolute imports
**Rule:** Test code must use absolute imports (`google.adk.*`) to match how users import ADK.
In tests, we use `google.adk` same as how our users uses.
```python
# DO - Use absolute imports
# DO
from google.adk.agents.llm_agent import LlmAgent
# DON'T - No relative imports in tests
# DON'T
from ..agents.llm_agent import LlmAgent
```
**Rationale:** Tests should exercise the same import paths that users will use, catching issues with the public API.
## ADK: Local testing
## ADK: Local Testing
### Unit tests
### Unit Tests
Run below command:
**Quick start:** Run all tests with:
```bash
pytest tests/unittests
$ pytest tests/unittests
```
**Recommended:** Match CI configuration before submitting PRs:
```bash
uv sync --extra test --extra eval --extra a2a && pytest tests/unittests
```
**Additional options:**
```bash
# Run tests in parallel for faster execution
pytest tests/unittests -n auto
# Run a specific test file during development
pytest tests/unittests/agents/test_llm_agent.py
# Python 3.9 compatibility mode (excludes features requiring 3.10+)
pytest tests/unittests \
--ignore=tests/unittests/a2a \
--ignore=tests/unittests/tools/mcp_tool \
--ignore=tests/unittests/artifacts/test_artifact_service.py
```
### Testing Philosophy
**Use real code over mocks:** ADK tests should use real implementations as much as possible instead of mocking. Only mock external dependencies like network calls or cloud services.
**Test interface behavior, not implementation details:** Tests should verify that the public API behaves correctly, not how it's implemented internally. This makes tests resilient to refactoring and ensures the contract with users remains intact.
**Test Requirements:**
- Fast and isolated tests where possible
- Use real ADK components; mock only external dependencies (LLM APIs, cloud services, etc.)
- Focus on testing public interfaces and behavior, not internal implementation
- Descriptive test names that explain what behavior is being tested
- High coverage for new features, edge cases, and error conditions
- Location: `tests/unittests/` following source structure
## Docstring and comments
### Comments - Explaining the Why, Not the What
@@ -432,49 +213,9 @@ The following changes are considered breaking and necessitate a MAJOR version
- Dependency Removal: Removing support for a previously integrated third-party
library or tool type.
## Commit Message Format (Required)
## Commit Message Format
**All commits must** follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) format.
**Format:**
```
<type>(<scope>): <description>
[optional body]
[optional footer]
```
**Common types:** `feat`, `fix`, `refactor`, `docs`, `test`, `chore`
**Examples:**
```
feat(agents): Add support for App pattern with plugins
fix(sessions): Prevent memory leak in session cleanup
refactor(tools): Unify environment variable enabled checks
```
**Rationale:** Conventional commits enable automated changelog generation and version management.
## Key Files and Locations
Quick reference to important project files:
- **Main config:** `pyproject.toml` (uses `flit_core` build backend)
- **Dependencies:** `uv.lock` (managed by `uv`)
- **Linting:** `pylintrc` (Google Python Style Guide)
- **Auto-format:** `autoformat.sh` (runs isort + pyink)
- **CLI entry point:** `src/google/adk/cli/cli_tools_click.py`
- **Web UI backend:** `src/google/adk/cli/adk_web_server.py`
- **Main exports:** `src/google/adk/__init__.py` (exports Agent, Runner)
- **Examples:** `contributing/samples/` (100+ agent implementations)
## Additional Resources
- **Documentation:** https://google.github.io/adk-docs
- **Samples:** https://github.com/google/adk-samples
- **Architecture Details:** `contributing/adk_project_overview_and_architecture.md`
- **Contributing Guide:** `CONTRIBUTING.md`
- **LLM Context:** `llms.txt` (summarized), `llms-full.txt` (comprehensive)
- Please use [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/)
format.
- If it's not a breaking change, please add #non-breaking tag. If it's a
breaking change, please add #breaking.
+10 -193
View File
@@ -1,189 +1,5 @@
# Changelog
## [1.18.0](https://github.com/google/adk-python/compare/v1.17.0...v1.18.0) (2025-11-05)
### Features
* **[ADK Visual Agent Builder]**
* Core Features
* Visual workflow designer for agent creation
* Support for multiple agent types (LLM, Sequential, Parallel, Loop, Workflow)
* Agent tool support with nested agent tools
* Built-in and custom tool integration
* Callback management for all ADK callback types (before/after agent, model, tool)
* Assistant to help you build your agents with natural language
* Assistant proposes and writes agent configuration yaml files for you
* Save to test with chat interfaces as normal
* Build and debug at the same time in adk web!
* **[Core]**
* Add support for extracting cache-related token counts from LiteLLM usage ([4f85e86](https://github.com/google/adk-python/commit/4f85e86fc3915f0e67312a39fe22451968d4f1b1))
* Expose the Python code run by the code interpreter in the logs ([a2c6a8a](https://github.com/google/adk-python/commit/a2c6a8a85cf4f556e9dacfe46cf384d13d964208))
* Add run_debug() helper method for quick agent experimentation ([0487eea](https://github.com/google/adk-python/commit/0487eea2abcd05d7efd123962d17b8c6c9a9d975))
* Allow injecting a custom Runner into `agent_to_a2a` ([156d235](https://github.com/google/adk-python/commit/156d23547915e8f7f5c6ba55e0362f4b133c3968))
* Support MCP prompts via the McpInstructionProvider class ([88032cf](https://github.com/google/adk-python/commit/88032cf5c56bb2d81842353605f9f5ab4b2206ff))
* **[Models]**
* Add model tracking to LiteLlm and introduce a LiteLLM with fallbacks demo ([d4c63fc](https://github.com/google/adk-python/commit/d4c63fc5629e7d70ad8b8185be09243a01e3428f))
* Add ApigeeLlm as a model that lets ADK Agent developers to connect with an Apigee proxy ([87dcb3f](https://github.com/google/adk-python/commit/87dcb3f7ba344a2ba7d9edfc4817c9e792d90bfc))
* **[Integrations]**
* Add example and fix for loading and upgrading old ADK session databases ([338c3c8](https://github.com/google/adk-python/commit/338c3c89c6bce7f3406f729013cedcd78b809a56))
* Add support for specifying logging level for adk eval cli command ([b1ff85f](https://github.com/google/adk-python/commit/b1ff85fb2347e3402eedd42e3673be7093a99548))
* Propagate LiteLLM finish_reason to LlmResponse for use in callbacks ([71aa564](https://github.com/google/adk-python/commit/71aa5645f6c3d91fd0e0ddb1ed564188c6727080))
* Allow LLM request to override the model used in the generate content async method in LiteLLM ([ce8f674](https://github.com/google/adk-python/commit/ce8f674a287368439ba11be3285902671e9bc75a))
* Add api key argument to Vertex Session and Memory services for Express Mode support ([9014a84](https://github.com/google/adk-python/commit/9014a849eab9f77b82db4a7f2053fb2a96282f03))
* Added support for enums as arguments for function tools ([240ef5b](https://github.com/google/adk-python/commit/240ef5beea9389911e8c03a6039b353befc716ac))
* Implement artifact_version related methods in GcsArtifactService ([e194ebb](https://github.com/google/adk-python/commit/e194ebb33c62bc40403ea852a88f77a9511b61a4))
* **[Services]**
* Add support for Vertex AI Express Mode when deploying to Agent Engine ([d4b2a8b](https://github.com/google/adk-python/commit/d4b2a8b49f98a9991cb44ac7ec6e538b81a08664))
* Remove custom polling logic for Vertex AI Session Service since LRO polling is supported in express mode ([546c2a6](https://github.com/google/adk-python/commit/546c2a68165f54e694664d5b6b6740566301782b))
* Make VertexAiSessionService fully asynchronous ([f7e2a7a](https://github.com/google/adk-python/commit/f7e2a7a40ef248dd6fbba9669503b0828a12f0cc))
* **[Tools]**
* Add Bigquery detect_anomalies tool ([9851340](https://github.com/google/adk-python/commit/9851340ad1df86d6f5c21e8984199573f239bb2b))
* Extend Bigquery detect_anomalies tool to support future data anomaly detection ([38ea749](https://github.com/google/adk-python/commit/38ea749c9cec8e65f5e768f49fd2de79b5545571))
* Add get_job_info tool to BigQuery toolset ([6429457](https://github.com/google/adk-python/commit/64294572c1c93590aa3c221015a5cb9b440ee948))
* **[Evals]**
* Add "final_session_state" to the EvalCase data model ([2274c4f](https://github.com/google/adk-python/commit/2274c4f3040b20da3690aa03272155776ca330c1))
* Marked expected_invocation as optional field on evaluator interface ([b17c8f1](https://github.com/google/adk-python/commit/b17c8f19e5fc67180d1bdc621f84cd43e357571c))
* Adds LLM-backed user simulator ([54c4ecc](https://github.com/google/adk-python/commit/54c4ecc73381cffa51cff01c7fb8a2ac59308c53))
* **[Observability]**
* Add BigQueryLoggingPlugin for event logging to BigQuery ([b7dbfed](https://github.com/google/adk-python/commit/b7dbfed4a3d4a0165e2c6e51594d1f547bec89d3))
* **[Live]**
* Add token usage to live events for bidi streaming ([6e5c0eb](https://github.com/google/adk-python/commit/6e5c0eb6e0474f5b908eb9df20328e7da85ebed9))
### Bug Fixes
* Reduce logging spam for MCP tools without authentication ([11571c3](https://github.com/google/adk-python/commit/11571c37ab948d43cbaa3a1d82522256dfe4d467))
* Fix typo in several files ([d2888a3](https://github.com/google/adk-python/commit/d2888a3766b87df2baaaa1a67a2235b1b80f138f))
* Disable SetModelResponseTool workaround for Vertex AI Gemini 2+ models ([6a94af2](https://github.com/google/adk-python/commit/6a94af24bf3367c05a5d405b7e7b79810a1fac4e))
* Bug when callback_context_invocation_context is missing in GlobalInstructionPlugin ([f81ebdb](https://github.com/google/adk-python/commit/f81ebdb622211031945eb06c3f00ff5208d94f9b))
* Support models slash prefix in model name extraction ([8dff850](https://github.com/google/adk-python/commit/8dff85099d67623dd6f4a707fb932ea55b8aaf9b))
* Do not consider events with state delta and no content as final response ([1ee93c8](https://github.com/google/adk-python/commit/1ee93c8bcb7ccd6f33658dc76b2095dd7e58aac9))
* Parameter filtering for CrewAI functions with **kwargs ([74a3500](https://github.com/google/adk-python/commit/74a3500fc5d4b07e80f914d83a0d91face28086c))
* Do not treat FinishReason.STOP as error case for LLM responses containing candidates with empty contents ([2f72ceb](https://github.com/google/adk-python/commit/2f72ceb49b452c5a1f257bce6adb004fa5d54472))
* Fixes null check for reflect_retry plugin sample ([86f0155](https://github.com/google/adk-python/commit/86f01550bd1b52d6d160e8bc54cecc6c4fe8611c))
* Creates evalset directory on evalset create ([6c3882f](https://github.com/google/adk-python/commit/6c3882f2d66f169d393171be280b6e6218b52a7c))
* Add ADK_DISABLE_LOAD_DOTENV environment variable that disables automatic loading of .env when running ADK cli, if set to true or 1 ([15afbcd](https://github.com/google/adk-python/commit/15afbcd1587d4102a4dc5c07c0c493917df9d6ea))
* Allow tenacity 9.0.0 ([ee8acc5](https://github.com/google/adk-python/commit/ee8acc58be7421a3e8eab07b051c45f9319f80dc))
* Output file uploading to artifact service should handle both base64 encoded and raw bytes ([496f8cd](https://github.com/google/adk-python/commit/496f8cd6bb36d3ba333d7ab1e94e7796d2960300))
* Correct message part ordering in A2A history ([5eca72f](https://github.com/google/adk-python/commit/5eca72f9bfd05c7c28a3d738391138a59a31167d))
* Change instruction insertion to respect tool call/response pairs ([1e6a9da](https://github.com/google/adk-python/commit/1e6a9daa63050936ab421f1f684935927aebc63e))
* DynamicPickleType to support MySQL dialect ([fc15c9a](https://github.com/google/adk-python/commit/fc15c9a0c3c043c0a61dce625b8cd1ee121b4baf))
* Enable usage metadata in LiteLLM streaming ([f9569bb](https://github.com/google/adk-python/commit/f9569bbb1afbc7f0e8b6e68599590471fd112b9f))
* Fix issue with MCP tools throwing an error ([1a4261a](https://github.com/google/adk-python/commit/1a4261ad4b66cdeb39d39110a086bd6112b17516))
* Remove redundant `format` field from LiteLLM content objects ([489c39d](https://github.com/google/adk-python/commit/489c39db01465e38ecbc2c7f32781c349b8cddc9))
* Update the contribution analysis tool to use original write mode ([54db3d4](https://github.com/google/adk-python/commit/54db3d4434e0706b83a589fa2499d11d439a6e4e))
### Improvements
* Add Community Repo section to README ([432d30a](https://github.com/google/adk-python/commit/432d30af486329aa83f89c5d5752749a85c0b843))
* Undo adding MCP tools output schema to FunctionDeclaration ([92a7d19](https://github.com/google/adk-python/commit/92a7d1957367d498de773761edd142d8c108d751))
* Refactor ADK README for clarity and consistency ([b0017ae](https://github.com/google/adk-python/commit/b0017aed4472c73c3b07e71f1d65ae97a5293547))
* Add support for reversed proxy in adk web ([a0df75b](https://github.com/google/adk-python/commit/a0df75b6fa35d837086decb8802dbf1c0a6637ad))
* Avoid rendering empty columns as part of detailed results rendering of eval results ([5cb35db](https://github.com/google/adk-python/commit/5cb35db921bf86b5ad0012046bd19fa7cc1e6abb))
* Clear the behavior of disallow_transfer_to_parent ([48ddd07](https://github.com/google/adk-python/commit/48ddd078941f9240b10f052b6de171c310bc2bc6))
* Disable the scheduled execution for issue triage workflow ([a02f321](https://github.com/google/adk-python/commit/a02f321f1bdb8be9ad1873db804e0e8393268dc3))
* Include delimiter when matching events from parent nodes in content processor ([b8a2b6c](https://github.com/google/adk-python/commit/b8a2b6c57080ae29d7a02df7d9fcc2f961d422d2))
* Improve Tau-bench ADK colab stability ([04dbc42](https://github.com/google/adk-python/commit/04dbc42e50ce40ef3924d1c259e425215e12c2e7))
* Implement ADK-based agent factory for Tau-bench ([c0c67c8](https://github.com/google/adk-python/commit/c0c67c8698d70ddb9ed958416661f232ef9a5ed8))
* Add util to run ADK LLM Agent with simulation environment ([87f415a](https://github.com/google/adk-python/commit/87f415a7c36a1f3b6ab84d1fe939726c6ef7f34e))
* Demonstrate CodeExecutor customization for environment setup ([8eeff35](https://github.com/google/adk-python/commit/8eeff35b35d7e1538a5c9662cc8369f6ff7962f8))
* Add sample agent for VertexAiCodeExecutor ([edfe553](https://github.com/google/adk-python/commit/edfe5539421d196ca4da14d3a37fac7b598f8c8d))
* Adds a new sample agent that demonstrates how to integrate PostgreSQL databases using the Model Context Protocol (MCP) ([45a2168](https://github.com/google/adk-python/commit/45a2168e0e6773e595ecfb825d7e4ab0a38c3a38))
* Add example for using ADK with Fast MCP sampling ([d3796f9](https://github.com/google/adk-python/commit/d3796f9b33251d28d05e6701f11e80f02a2a49e1))
## [1.17.0](https://github.com/google/adk-python/compare/v1.16.0...v1.17.0) (2025-10-22)
### Features
* **[Core]**
* Add a service registry to provide a generic way to register custom service implementations to be used in FastAPI server. See short instruction [here](https://github.com/google/adk-python/discussions/3175#discussioncomment-14745120). ([391628f](https://github.com/google/adk-python/commit/391628fcdc7b950c6835f64ae3ccab197163c990))
* Add the ability to rewind a session to before a previous invocation ([9dce06f](https://github.com/google/adk-python/commit/9dce06f9b00259ec42241df4f6638955e783a9d1))
* Support resuming a parallel agent with multiple branches paused on tool confirmation requests ([9939e0b](https://github.com/google/adk-python/commit/9939e0b087094038b90d86c2fd35c26dd63f1157))
* Support content union as static instruction ([cc24d61](https://github.com/google/adk-python/commit/cc24d616f80c0eba2b09239b621cf3d176f144ea))
* **[Evals]**
* ADK cli allows developers to create an eval set and add an eval case ([ae139bb](https://github.com/google/adk-python/commit/ae139bb461c2e7c6be154b04f3f2c80919808d31))
* **[Integrations]**
* Allow custom request and event converters in A2aAgentExecutor ([a17f3b2](https://github.com/google/adk-python/commit/a17f3b2e6d2d48c433b42e27763f3d6df80243ca))
* **[Observability]**
* Env variable for disabling llm_request and llm_response in spans ([e50f05a](https://github.com/google/adk-python/commit/e50f05a9fc94834796876f7f112f344f788f202e))
* **[Services]**
* Allow passing extra kwargs to create_session of VertexAiSessionService ([6a5eac0](https://github.com/google/adk-python/commit/6a5eac0bdc9adc6907a28f65a3d4d7234e863049))
* Implement new methods in in-memory artifact service to support custom metadata, artifact versions, etc. ([5a543c0](https://github.com/google/adk-python/commit/5a543c00df2f7a66018df8a67efcf4ce44d4e0e4))
* Add create_time and mime_type to ArtifactVersion ([2c7a342](https://github.com/google/adk-python/commit/2c7a34259395b1294319118d0f3d1b3b867b44d6))
* Support returning all sessions when user id is none ([141318f](https://github.com/google/adk-python/commit/141318f77554ae4eb5a360bea524e98eff4a086c))
* **[Tools]**
* Support additional headers for Google API toolset ([ed37e34](https://github.com/google/adk-python/commit/ed37e343f0c997d3ee5dc98888c5e0dbd7f2a2b6))
* Introduces a new AgentEngineSandboxCodeExecutor class that supports executing agent-generated code using the Vertex AI Code Execution Sandbox API ([ee39a89](https://github.com/google/adk-python/commit/ee39a891106316b790621795b5cc529e89815a98))
* Support dynamic per-request headers in MCPToolset ([6dcbb5a](https://github.com/google/adk-python/commit/6dcbb5aca642290112a7c81162b455526c15cd14))
* Add `bypass_multi_tools_limit` option to GoogleSearchTool and VertexAiSearchTool ([9a6b850](https://github.com/google/adk-python/commit/9a6b8507f06d8367488aac653efecf665619516c), [6da7274](https://github.com/google/adk-python/commit/6da727485898137948d72906d86d78b6db6331ac))
* Extend `ReflectAndRetryToolPlugin` to support hallucinating function calls ([f51380f](https://github.com/google/adk-python/commit/f51380f9ea4534591eda76bef27407c0aa7c3fae))
* Add require_confirmation param for MCP tool/toolset ([78e74b5](https://github.com/google/adk-python/commit/78e74b5bf2d895d72025a44dbcf589f543514a50))
* **[UI]**
* Granular per agent speech configuration ([409df13](https://github.com/google/adk-python/commit/409df1378f36b436139aa909fc90a9e9a0776b3a))
### Bug Fixes
* Returns dict as result from McpTool to comply with BaseTool expectations ([4df9263](https://github.com/google/adk-python/commit/4df926388b6e9ebcf517fbacf2f5532fd73b0f71))
* Fixes the identity prompt to be one line ([7d5c6b9](https://github.com/google/adk-python/commit/7d5c6b9acf0721dd230f08df919c7409eed2b7d0))
* Fix the broken langchain importing caused their 1.0.0 release ([c850da3](https://github.com/google/adk-python/commit/c850da3a07ec1441037ced1b654d8aacacd277ab))
* Fix BuiltInCodeExecutor to support visualizations ([ce3418a](https://github.com/google/adk-python/commit/ce3418a69de56570847d45f56ffe7139ab0a47aa))
* Relax runner app-name enforcement and improve agent origin inference ([dc4975d](https://github.com/google/adk-python/commit/dc4975dea9fb79ad887460659f8f397a537ee38f))
* Improve error message when adk web is run in wrong directory ([4a842c5](https://github.com/google/adk-python/commit/4a842c5a1334c3ee01406f796651299589fe12ab))
* Handle App objects in eval and graph endpoints ([0b73a69](https://github.com/google/adk-python/commit/0b73a6937bd84a41f79a9ada3fc782dca1d6fb11))
* Exclude `additionalProperties` from Gemini schemas ([307896a](https://github.com/google/adk-python/commit/307896aeceeb97efed352bc0217bae10423e5da6))
* Overall eval status should be NOT_EVALUATED if no invocations were evaluated ([9fbed0b](https://github.com/google/adk-python/commit/9fbed0b15afb94ec8c0c7ab60221bbc97e481b06))
* Create context cache only when prefix matches with previous request ([9e0b1fb](https://github.com/google/adk-python/commit/9e0b1fb62b06de7ecb79bf77d54a999167d001e1))
* Handle `App` instances returned by `agent_loader.load_agent` ([847df16](https://github.com/google/adk-python/commit/847df1638cbf1686aa43e8e094121d4e23e40245))
* Add support for file URIs in LiteLLM content conversion ([85ed500](https://github.com/google/adk-python/commit/85ed500871ff55c74d16e809ddae0d4db66cbc3a))
* Only exclude scores that are None ([998264a](https://github.com/google/adk-python/commit/998264a5b1b98ac660fcc1359fb2d25c84fa0d87))
* Better handling the A2A streaming tasks ([bddc70b](https://github.com/google/adk-python/commit/bddc70b5d004ba5304fe05bcbf6e08210f0e6131))
* Correctly populate context_id in remote_a2a_agent library ([2158b3c](https://github.com/google/adk-python/commit/2158b3c91531e9125761f211f125d9ab41a55e10))
* Remove unnecessary Aclosing ([2f4f561](https://github.com/google/adk-python/commit/2f4f5611bdb30bd5eb2fdb3a70f43d748371392f))
* Fix pickle data was truncated error in database session using MySql ([36c96ec](https://github.com/google/adk-python/commit/36c96ec5b356109b7c874c85d8bb24f0bf6c050d))
### Improvements
* Improve hint message in agent loader ([fe1fc75](https://github.com/google/adk-python/commit/fe1fc75c15a7983829bbe0b023f4b612b1e5c018))
* Fixes MCPToolset --> McpToolset in various places ([d4dc645](https://github.com/google/adk-python/commit/d4dc6454783f747120d407d0dc2cb78f53598d83))
* Add span for context caching handling and new cache creation ([a2d9f13](https://github.com/google/adk-python/commit/a2d9f13fa1d31e00ba9493fba321ca151cdd9366))
* Checks gemini version for `2 and above` for gemini-builtin tools ([0df6759](https://github.com/google/adk-python/commit/0df67599c0eb54a9a5df51af06483b40058953bf))
* Refactor and fix state management in the session service ([8b3ed05](https://github.com/google/adk-python/commit/8b3ed059c24903e8aca0a09d9d503b48af7df850))
* Update agent builder instructions and remove run command details ([89344da](https://github.com/google/adk-python/commit/89344da81364d921f778c8bbea93e1df6ad1097e))
* Clarify how to use adk built-in tool in instruction ([d22b8bf](https://github.com/google/adk-python/commit/d22b8bf8907e723f618dfd18e90dd0a5dbc9518c))
* Delegate the agent state reset logic to LoopAgent ([bb1ea74](https://github.com/google/adk-python/commit/bb1ea74924127d65d763a45b869da3d4ff4d5c5a))
* Adjust the instruction about default model ([214986e](https://github.com/google/adk-python/commit/214986ebeb53b2ef34c8aa37cd6403106de82c1b))
* Migrate invocation_context to callback_context ([e2072af](https://github.com/google/adk-python/commit/e2072af69f40474431b6749b7b9dc22fbcbc7730))
* Correct the callback signatures ([fa84bcb](https://github.com/google/adk-python/commit/fa84bcb5756773eadff486b99c9bd416b4faa9c6))
* Set default for `bypass_multi_tools_limit` to False for GoogleSearchTool and VertexAiSearchTool ([6da7274](https://github.com/google/adk-python/commit/6da727485898137948d72906d86d78b6db6331ac))
* Add more clear instruction to the doc updater agent about one PR for each recommended change ([b21d0a5](https://github.com/google/adk-python/commit/b21d0a50d610407be2f10b73a91274840ffdfe18))
* Add a guideline to avoid content deletion ([16b030b](https://github.com/google/adk-python/commit/16b030b2b25a9b0b489e47b4b148fc4d39aeffcb))
* Add an sample agent for the `ReflectAndRetryToolPlugin` ([9b8a4aa](https://github.com/google/adk-python/commit/9b8a4aad6fe65ef37885e5c3368d2799a2666534))
* Improve error message when adk web is run in wrong directory ([4a842c5](https://github.com/google/adk-python/commit/4a842c5a1334c3ee01406f796651299589fe12ab))
* Add an sample agent for the `ReflectAndRetryToolPlugin` ([9b8a4aa](https://github.com/google/adk-python/commit/9b8a4aad6fe65ef37885e5c3368d2799a2666534))
* Add span for context caching handling and new cache creation ([a2d9f13](https://github.com/google/adk-python/commit/a2d9f13fa1d31e00ba9493fba321ca151cdd9366))
* Disable the scheduled execution for issue triage workflow ([bae2102](https://github.com/google/adk-python/commit/bae21027d9bd7f811bed638ecce692262cb33fe5))
* Correct the callback signatures ([fa84bcb](https://github.com/google/adk-python/commit/fa84bcb5756773eadff486b99c9bd416b4faa9c6))
### Documentation
* Format README.md for samples ([0bdba30](https://github.com/google/adk-python/commit/0bdba3026345872fb907aedd1ed75e4135e58a30))
* Bump models in llms and llms-full to Gemini 2.5 ([ce46386](https://github.com/google/adk-python/commit/ce4638651f376fb6579993d8468ae57198134729))
* Update gemini_llm_connection.py - typo spelling correction ([e6e2767](https://github.com/google/adk-python/commit/e6e2767c3901a14187f5527540f318317dd6c8e3))
* Announce the first ADK Community Call in the README ([731bb90](https://github.com/google/adk-python/commit/731bb9078d01359ae770719a8f5c003680ed9f3e))
## [1.16.0](https://github.com/google/adk-python/compare/v1.15.1...v1.16.0) (2025-10-08)
### Features
@@ -538,7 +354,7 @@ with Bigtable for building AI Agent applications(experimental feature) ([a953807
### Improvements
* Add GitHub workflow config for the ADK Answering agent ([8dc0c94](https://github.com/google/adk-python/commit/8dc0c949afb9024738ff7ac1b2c19282175c3200))
* Add Github workflow config for the ADK Answering agent ([8dc0c94](https://github.com/google/adk-python/commit/8dc0c949afb9024738ff7ac1b2c19282175c3200))
* Import AGENT_CARD_WELL_KNOWN_PATH from adk instead of from a2a directly ([37dae9b](https://github.com/google/adk-python/commit/37dae9b631db5060770b66fce0e25cf0ffb56948))
* Make `LlmRequest.LiveConnectConfig` field default to a factory ([74589a1](https://github.com/google/adk-python/commit/74589a1db7df65e319d1ad2f0676ee0cf5d6ec1d))
* Update the prompt to make the ADK Answering Agent more objective ([2833030](https://github.com/google/adk-python/commit/283303032a174d51b8d72f14df83c794d66cb605))
@@ -597,13 +413,14 @@ with Bigtable for building AI Agent applications(experimental feature) ([a953807
### Features
* [Core]Add agent card builder ([18f5bea](https://github.com/google/adk-python/commit/18f5bea411b3b76474ff31bfb2f62742825b45e5))
* [Core]Add a to_a2a util to convert adk agent to A2A ASGI application ([a77d689](https://github.com/google/adk-python/commit/a77d68964a1c6b7659d6117d57fa59e43399e0c2))
* [Core]Add an to_a2a util to convert adk agent to A2A ASGI application ([a77d689](https://github.com/google/adk-python/commit/a77d68964a1c6b7659d6117d57fa59e43399e0c2))
* [Core]Add camel case converter for agents ([0e173d7](https://github.com/google/adk-python/commit/0e173d736334f8c6c171b3144ac6ee5b7125c846))
* [Evals]Use LocalEvalService to run all evals in cli and web ([d1f182e](https://github.com/google/adk-python/commit/d1f182e8e68c4a5a4141592f3f6d2ceeada78887))
* [Evals]Enable FinalResponseMatchV2 metric as an experiment ([36e45cd](https://github.com/google/adk-python/commit/36e45cdab3bbfb653eee3f9ed875b59bcd525ea1))
* [Models]Add support for `model-optimizer-*` family of models in vertex ([ffe2bdb](https://github.com/google/adk-python/commit/ffe2bdbe4c2ea86cc7924eb36e8e3bb5528c0016))
* [Services]Added a sample for History Management ([67284fc](https://github.com/google/adk-python/commit/67284fc46667b8c2946762bc9234a8453d48a43c))
* [Services]Support passing fully qualified agent engine resource name when constructing session service and memory service ([2e77804](https://github.com/google/adk-python/commit/2e778049d0a675e458f4e35fe4104ca1298dbfcf))
* [Services]Support passing fully qualified agent engine resource name when constructing session service and memory service ([2e77804](https://github.com/google/adk-python/commit/2e778049d0a675e458f4e
35fe4104ca1298dbfcf))
* [Tools]Add ComputerUseToolset ([083dcb4](https://github.com/google/adk-python/commit/083dcb44650eb0e6b70219ede731f2fa78ea7d28))
* [Tools]Allow toolset to process llm_request before tools returned by it ([3643b4a](https://github.com/google/adk-python/commit/3643b4ae196fd9e38e52d5dc9d1cd43ea0733d36))
* [Tools]Support input/output schema by fully-qualified code reference ([dfee06a](https://github.com/google/adk-python/commit/dfee06ac067ea909251d6fb016f8331065d430e9))
@@ -716,7 +533,7 @@ with Bigtable for building AI Agent applications(experimental feature) ([a953807
### Documentation
* Update the a2a example link in README.md [d0fdfb8](https://github.com/google/adk-python/commit/d0fdfb8c8e2e32801999c81de8d8ed0be3f88e76)
* Update the a2a exmaple link in README.md [d0fdfb8](https://github.com/google/adk-python/commit/d0fdfb8c8e2e32801999c81de8d8ed0be3f88e76)
* Adds AGENTS.md to provide relevant project context for the Gemini CLI [37108be](https://github.com/google/adk-python/commit/37108be8557e011f321de76683835448213f8515)
* Update CONTRIBUTING.md [ffa9b36](https://github.com/google/adk-python/commit/ffa9b361db615ae365ba62c09a8f4226fb761551)
* Add adk project overview and architecture [28d0ea8](https://github.com/google/adk-python/commit/28d0ea876f2f8de952f1eccbc788e98e39f50cf5)
@@ -911,7 +728,7 @@ with Bigtable for building AI Agent applications(experimental feature) ([a953807
* Fix typos in README for sample bigquery_agent and oauth_calendar_agent ([9bdd813](https://github.com/google/adk-python/commit/9bdd813be15935af5c5d2a6982a2391a640cab23))
* Make tool_call one span for telemetry and renamed to execute_tool ([999a7fe](https://github.com/google/adk-python/commit/999a7fe69d511b1401b295d23ab3c2f40bccdc6f))
* Use media type in chat window. Remove isArtifactImage and isArtifactAudio reference ([1452dac](https://github.com/google/adk-python/commit/1452dacfeb6b9970284e1ddeee6c4f3cb56781f8))
* Set output_schema correctly for LiteLlm ([6157db7](https://github.com/google/adk-python/commit/6157db77f2fba4a44d075b51c83bff844027a147))
* Set output_schema correctly for LiteLllm ([6157db7](https://github.com/google/adk-python/commit/6157db77f2fba4a44d075b51c83bff844027a147))
* Update pending event dialog style ([1db601c](https://github.com/google/adk-python/commit/1db601c4bd90467b97a2f26fe9d90d665eb3c740))
* Remove the gap between event holder and image ([63822c3](https://github.com/google/adk-python/commit/63822c3fa8b0bdce2527bd0d909c038e2b66dd98))
@@ -939,7 +756,7 @@ with Bigtable for building AI Agent applications(experimental feature) ([a953807
## 1.1.1
### Features
* Add [BigQuery first-party tools](https://github.com/google/adk-python/commit/d6c6bb4b2489a8b7a4713e4747c30d6df0c07961).
* Add BigQuery first-party tools. See [here](https://github.com/google/adk-python/commit/d6c6bb4b2489a8b7a4713e4747c30d6df0c07961) for more details.
## 1.1.0
@@ -1075,7 +892,7 @@ with Bigtable for building AI Agent applications(experimental feature) ([a953807
* Fix google search reading undefined for `renderedContent`.
### Miscellaneous Chores
* Docstring improvements, typo fixings, github action to enforce code styles on formatting and imports, etc.
* Docstring improvements, typo fixings, github action to enfore code styles on formatting and imports, etc.
## 0.3.0
@@ -1114,7 +931,7 @@ with Bigtable for building AI Agent applications(experimental feature) ([a953807
### âš  BREAKING CHANGES
* Fix typo in method name in `Event`: has_trailing_code_execution_result --> has_trailing_code_execution_result.
* Fix typo in method name in `Event`: has_trailing_code_exeuction_result --> has_trailing_code_execution_result.
### Features
@@ -1144,7 +961,7 @@ with Bigtable for building AI Agent applications(experimental feature) ([a953807
### Miscellaneous Chores
* Adds unit tests in GitHub action.
* Adds unit tests in Github action.
* Improves test coverage.
* Various typo fixes.
+3 -5
View File
@@ -57,9 +57,7 @@ information on using pull requests.
### Requirement for PRs
- All PRs, other than small documentation or typo fixes, should have a Issue
associated. If a relevant issue doesn't exist, please create one first or
you may instead describe the bug or feature directly within the PR
description, following the structure of our issue templates.
associated. If not, please create one.
- Small, focused PRs. Keep changes minimal—one concern per PR.
- For bug fixes or features, please provide logs or screenshot after the fix
is applied to help reviewers better understand the fix.
@@ -234,6 +232,6 @@ has resources that is helpful for contributors.
## Vibe Coding
If you want to contribute by leveraging vibe coding, the AGENTS.md
If you want to contribute by leveraging viber coding, the AGENTS.md
(https://github.com/google/adk-python/tree/main/AGENTS.md) could be used as
context to your LLM.
context to your LLM.
+43 -27
View File
@@ -11,7 +11,7 @@
<img src="https://raw.githubusercontent.com/google/adk-python/main/assets/agent-development-kit.png" width="256"/>
</h2>
<h3 align="center">
An open-source, code-first Python framework for building, evaluating, and deploying sophisticated AI agents with flexibility and control.
An open-source, code-first Python toolkit for building, evaluating, and deploying sophisticated AI agents with flexibility and control.
</h3>
<h3 align="center">
Important Links:
@@ -22,26 +22,52 @@
</h3>
</html>
Agent Development Kit (ADK) is a flexible and modular framework that applies
software development principles to AI agent creation. It is designed to
simplify building, deploying, and orchestrating agent workflows, from simple
tasks to complex systems. While optimized for Gemini, ADK is model-agnostic,
deployment-agnostic, and compatible with other frameworks.
Agent Development Kit (ADK) is a flexible and modular framework for developing and deploying AI agents. 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.
---
## 🔥 ADK's very first community call on Oct 15
Join our ADK Community Call! Our first virtual community call is on Oct 15!
Meet our team, and talk with us about our roadmap and how to contribute.
First Call Details:
Topic: ADK Roadmap
Date: October 15, 2025
Time: 9:30-10:30am PST
Meeting link:
[Join the call](http://meet.google.com/gjm-gfim-ctz)
Add to your calendar
[Event calendar invite](https://calendar.google.com/calendar/event?action=TEMPLATE&tmeid=MDUydWo1dHV1dHFtNzJuM3E0bmEyMW12ZnZfMjAyNTEwMTVUMTYzMDAwWiBjXzljNWVjODhhMmQyYWU5YjY5Mzk4ODU1MGZkNDA5MjVmYjgxYjM4MTI1NGNjYTgzNmRkMjMwNzRiMjNmYzcyZDVAZw&tmsrc=c_9c5ec88a2d2ae9b693988550fd40925fb81b381254cca836dd23074b23fc72d5%40group.calendar.google.com), [.ics file](https://calendar.google.com/calendar/ical/c_9c5ec88a2d2ae9b693988550fd40925fb81b381254cca836dd23074b23fc72d5%40group.calendar.google.com/public/basic.ics), [ADK community calendar](https://calendar.google.com/calendar/embed?src=c_9c5ec88a2d2ae9b693988550fd40925fb81b381254cca836dd23074b23fc72d5%40group.calendar.google.com&ctz=America%2FLos_Angeles), [ADK Community Call RSVP](https://google.qualtrics.com/jfe/form/SV_3K0RJZ64H1BexqS)
Agenda:
[Julia] ADK Roadmap
[ Bo & Hangfei] Eng Deep Dive: Context Caching
[Kris] How to Contribute
[Shubham] Upcoming Events
---
## 🔥 What's new
- **Custom Service Registration**: Add a service registry to provide a generic way to register custom service implementations to be used in FastAPI server. See short instruction [here](https://github.com/google/adk-python/discussions/3175#discussioncomment-14745120). ([391628f](https://github.com/google/adk-python/commit/391628fcdc7b950c6835f64ae3ccab197163c990))
- **Context compaction**: Supports context compaction to reduce context length. Here is a [sample](https://github.com/google/adk-python/blob/main/contributing/samples/hello_world_app/agent.py#L156) and [compaction config](https://github.com/google/adk-python/blob/main/src/google/adk/apps/app.py#L51).
- **Rewind**: Add the ability to rewind a session to before a previous invocation ([9dce06f](https://github.com/google/adk-python/commit/9dce06f9b00259ec42241df4f6638955e783a9d1)).
- **Resumability**: Support pause and resume an invocation in ADK.
- **New CodeExecutor**: Introduces a new AgentEngineSandboxCodeExecutor class that supports executing agent-generated code using the Vertex AI Code Execution Sandbox API ([ee39a89](https://github.com/google/adk-python/commit/ee39a891106316b790621795b5cc529e89815a98))
- **ReflectRetryToolPlugin**: Add [`ReflectRetryToolPlugin`](https://github.com/google/adk-python/blob/main/src/google/adk/plugins/reflect_retry_tool_plugin.py) to reflect from errors and retry with different arguments when tool errors.
- **Search tool**: Support using Google built-in search and built-in `VertexAiSearchTool` with other tools in the same agent.
## ✨ Key Features
- **Rich Tool Ecosystem**: Utilize pre-built tools, custom functions,
OpenAPI specs, MCP tools or integrate existing tools to give agents diverse
OpenAPI specs, or integrate existing tools to give agents diverse
capabilities, all for tight integration with the Google ecosystem.
- **Code-First Development**: Define agent logic, tools, and orchestration
@@ -58,6 +84,13 @@ deployment-agnostic, and compatible with other frameworks.
- **Deploy Anywhere**: Easily containerize and deploy agents on Cloud Run or
scale seamlessly with Vertex AI Agent Engine.
## 🤖 Agent2Agent (A2A) Protocol and ADK Integration
For remote agent-to-agent communication, ADK integrates with the
[A2A protocol](https://github.com/google-a2a/A2A/).
See this [example](https://github.com/a2aproject/a2a-samples/tree/main/samples/python/agents)
for how they can work together.
## 🚀 Installation
### Stable Release (Recommended)
@@ -81,13 +114,6 @@ pip install git+https://github.com/google/adk-python.git@main
Note: The development version is built directly from the latest code commits. While it includes the newest fixes and features, it may also contain experimental changes or bugs not present in the stable release. Use it primarily for testing upcoming changes or accessing critical fixes before they are officially released.
## 🤖 Agent2Agent (A2A) Protocol and ADK Integration
For remote agent-to-agent communication, ADK integrates with the
[A2A protocol](https://github.com/google-a2a/A2A/).
See this [example](https://github.com/a2aproject/a2a-samples/tree/main/samples/python/agents)
for how they can work together.
## 📚 Documentation
Explore the full documentation for detailed guides on building, evaluating, and
@@ -155,20 +181,10 @@ We welcome contributions from the community! Whether it's bug reports, feature r
- [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.
## Community Repo
We have [adk-python-community repo](https://github.com/google/adk-python-community)that is home to a growing ecosystem of community-contributed tools, third-party
service integrations, and deployment scripts that extend the core capabilities
of the ADK.
## Vibe Coding
If you are to develop agent via vibe coding the [llms.txt](./llms.txt) and the [llms-full.txt](./llms-full.txt) can be used as context to LLM. While the former one is a summarized one and the later one has the full information in case your LLM has big enough context window.
## Community Events
- [Completed] ADK's 1st community meeting on Wednesday, October 15, 2025. Remember to [join our group](https://groups.google.com/g/adk-community) to get access to the [recording](https://drive.google.com/file/d/1rpXDq5NSH8-MyMeYI6_5pZ3Lhn0X9BQf/view), and [deck](https://docs.google.com/presentation/d/1_b8LG4xaiadbUUDzyNiapSFyxanc9ZgFdw7JQ6zmZ9Q/edit?slide=id.g384e60cdaca_0_658&resourcekey=0-tjFFv0VBQhpXBPCkZr0NOg#slide=id.g384e60cdaca_0_658).
## đź“„ License
This project is licensed under the Apache 2.0 License - see the [LICENSE](LICENSE) file for details.
@@ -46,7 +46,7 @@ root_agent = Agent(
Use the provided tools to conduct various operations on users' data in Google BigQuery.
Scenario 1:
The user wants to query their bigquery datasets
The user wants to query their biguqery datasets
Use bigquery_datasets_list to query user's datasets
Scenario 2:
@@ -99,7 +99,7 @@ Agent: âś… Great news! Your reimbursement has been approved by the manager. Proc
The human-in-the-loop process follows this pattern:
1. **Initial Call**: Root agent delegates approval request to remote approval agent for amounts >$100
2. **Pending Response**: Remote approval agent returns immediate response with `status: "pending"` and ticket ID and surface the approval request to root agent
2. **Pending Response**: Remote approval agent returns immediate response with `status: "pending"` and ticket ID and serface the approval request to root agent
3. **Agent Acknowledgment**: Root agent informs user about pending approval status
4. **Human Interaction**: Human manager interacts with root agent to review and approve/reject the request
5. **Updated Response**: Root agent receives updated tool response with approval decision and send it to remote agent
@@ -26,6 +26,7 @@ from google.adk.tools import AgentTool
from google.adk.tools import FunctionTool
from google.genai import types
from .sub_agents.adk_knowledge_agent import create_adk_knowledge_agent
from .sub_agents.google_search_agent import create_google_search_agent
from .sub_agents.url_context_agent import create_url_context_agent
from .tools.cleanup_unused_files import cleanup_unused_files
@@ -33,7 +34,6 @@ from .tools.delete_files import delete_files
from .tools.explore_project import explore_project
from .tools.read_config_files import read_config_files
from .tools.read_files import read_files
from .tools.search_adk_knowledge import search_adk_knowledge
from .tools.search_adk_source import search_adk_source
from .tools.write_config_files import write_config_files
from .tools.write_files import write_files
@@ -69,9 +69,11 @@ class AgentBuilderAssistant:
# - Maintains compatibility with existing ADK tool ecosystem
# Built-in ADK tools wrapped as sub-agents
adk_knowledge_agent = create_adk_knowledge_agent()
google_search_agent = create_google_search_agent()
url_context_agent = create_url_context_agent()
agent_tools = [
AgentTool(adk_knowledge_agent),
AgentTool(google_search_agent),
AgentTool(url_context_agent),
]
@@ -97,8 +99,6 @@ class AgentBuilderAssistant:
FunctionTool(cleanup_unused_files),
# ADK source code search (regex-based)
FunctionTool(search_adk_source), # Search ADK source with regex
# ADK knowledge search
FunctionTool(search_adk_knowledge), # Search ADK knowledge base
]
# Combine all tools
@@ -12,18 +12,6 @@ Help users design, build, and configure sophisticated multi-agent systems for th
When users ask informational questions like "find me examples", "show me samples", "how do I", etc., they want INFORMATION ONLY. Provide the information and stop. Do not offer to create anything or ask for root directories.
## ROOT AGENT CLASS RULE
**NON-NEGOTIABLE**: `root_agent.yaml` MUST always declare `agent_class: LlmAgent`.
**NEVER** set `root_agent.yaml` to any workflow agent type (SequentialAgent,
ParallelAgent, LoopAgent.) All workflow coordination must stay in sub-agents, not the root file.
**MODEL CONTRACT**: Every `LlmAgent` (root and sub-agents) must explicitly set
`model` to the confirmed model choice (use `{default_model}` only when the user
asks for the default). Never omit this field or rely on a global default.
**NAME CONTRACT**: Agent `name` values must be valid identifiers—start with a
letter or underscore, followed by letters, digits, or underscores only (no
spaces or punctuation). Require users to adjust names that violate this rule.
## Core Capabilities
1. **Agent Architecture Design**: Analyze requirements and suggest appropriate agent types (LlmAgent, SequentialAgent, ParallelAgent, LoopAgent)
@@ -87,10 +75,6 @@ Always reference this schema when creating configurations to ensure compliance.
**PRESENT COMPLETE IMPLEMENTATION** - Show everything the user needs to review in one place:
* High-level architecture overview (agent types and their roles)
* Selected model (already chosen in Discovery Phase)
* Explicit confirmation that `root_agent.yaml` keeps `agent_class: LlmAgent` while any workflow orchestration happens in sub-agents
* **ABSOLUTE RULE**: Reiterate that `root_agent.yaml` can NEVER become a workflow agent; it must stay an LlmAgent in every plan and output
* **MODEL FIELD ENFORCEMENT**: Show every `LlmAgent` block with a `model`
field populated with the confirmed model name—call it out if missing
* **Complete YAML configuration files** - Show full content of all YAML files
* **Complete Python files** - Show full content of all Python tool/callback files
* File structure with paths
@@ -126,9 +110,6 @@ Always reference this schema when creating configurations to ensure compliance.
**STEP 3: CLEANUP**
1. Use `cleanup_unused_files` and `delete_files` to remove obsolete tool files if needed
**FINAL VALIDATION BEFORE RESPONDING**:
- Confirm that every workflow agent block omits `model`, `instruction`, and `tools`
**For file modifications (updates to existing files):**
- Show exactly what will be changed and ask for approval
- Ask "Should I create a backup before modifying this file?" if modifying existing files
@@ -136,27 +117,6 @@ Always reference this schema when creating configurations to ensure compliance.
**YAML Configuration Requirements:**
- Main agent file MUST be named `root_agent.yaml`
- **`agent_class` field**:
* Always declare `agent_class` explicitly for every agent block (the loader defaults to `LlmAgent`, but we require clarity)
* Use `agent_class: LlmAgent` when the agent talks directly to an LLM
- **`model` field for LlmAgents**:
* Every `LlmAgent` definition (root or sub-agent) MUST specify `model`
explicitly; insert the user-confirmed model or `{default_model}` if they
ask for the default
* Never rely on global defaults or omit `model` because doing so crashes
canonicalization
- **Agent `name` field**:
* Must be a valid identifier: begins with [A-Za-z_] and contains only
letters, digits, or underscores afterward
* Reject or rename entries like `Paper Analyzer` or `Vacation Planner`; use
`Paper_Analyzer` instead
- **đźš« Workflow agent field ban**: Workflow orchestrators (`SequentialAgent`,
`ParallelAgent`, `LoopAgent`, etc.) must NEVER include `model`, `instruction`,
or `tools`. Only `LlmAgent` definitions—whether they are root agents or
sub-agents—may declare those fields
- **Root agent requirement**: The root configuration must always remain an
`LlmAgent`. Never convert the root agent into a workflow agent.
- **Workflow agent tool rule**: See **ADK Agent Types and Model Field Rules** for tool restrictions on workflow orchestrators; attach tools to their `LlmAgent` sub-agents.
- **Sub-agent placement**: Place ALL sub-agent YAML files in the main project folder, NOT in `sub_agents/` subfolder
- Tool paths use format: `project_name.tools.module.function_name` (must start with project folder name, no `.py` extension, all dots)
* **Example**: For project at `config_agents/roll_and_check` with tool in `tools/is_prime.py`, use: `roll_and_check.tools.is_prime.is_prime`
@@ -172,7 +132,7 @@ Always reference this schema when creating configurations to ensure compliance.
**🚨 CRITICAL: Built-in Tools vs Custom Tools**
**ADK Built-in Tools** (use directly, NO custom Python file needed):
- **Naming**: Use the exported name with no dots (e.g., `google_search`, NOT `google.adk.tools.google_search`; never invent new labels like `GoogleSearch`)
- **Naming**: Use simple name WITHOUT dots (e.g., `google_search`, NOT `google.adk.tools.google_search`)
- **No custom code**: Do NOT create Python files for built-in tools
- **Available built-in tools**:
* `google_search` - Google Search tool
@@ -186,7 +146,6 @@ Always reference this schema when creating configurations to ensure compliance.
* `load_memory` - Load memory
* `preload_memory` - Preload memory
* `transfer_to_agent` - Transfer to another agent
* ⚠️ Do **not** declare `transfer_to_agent` in YAML when the agent has `sub_agents`; ADK injects this tool automatically, and duplicating it causes Gemini errors (`Duplicate function declaration: transfer_to_agent`).
**Example - Built-in Tool Usage (CORRECT):**
```yaml
@@ -202,19 +161,6 @@ tools:
```
**DO NOT create Python files like `tools/google_search_tool.py` for built-in tools!**
- **đźš« Tool Hallucination Ban**
- Use only the built-in tool names enumerated in the **ADK Built-in Tools**
list above; never invent additional built-in labels.
- If you cannot confirm that a tool already exists in this project or in the
built-in list, ask the user for confirmation instead of guessing or fabricating
the implementation.
- Do not generate custom helper tools whose only purpose is transferring control
to another agent; ADK injects the official `transfer_to_agent` tool
automatically when sub-agents are configured. Avoid creating look-alikes such
as `transfer_to_agent_tool`.
- `tool_code` is reserved by some runtimes for code execution. Do not reuse that
name for ADK tools or dotted paths.
**Custom Tools** (require Python implementation):
- **Naming**: Use dotted path: `{{project_folder_name}}.tools.{{module_name}}.{{function_name}}`
- **Require Python file**: Must create actual Python file in `tools/` directory
@@ -251,9 +197,10 @@ tools:
- **Match user requirements exactly**: Generate the specific functions requested
- **Use proper parameter types**: Don't use generic `parameter: str` when specific types are needed
- **Implement when possible**: Write actual working code for simple, well-defined functions
- **Tool file organization**:
* Place tool code inside a `tools/` package and include `tools/__init__.py` so dotted imports resolve.
* Prefer one tool per module (e.g., `tools/dice_tool.py`, `tools/prime_tool.py`); sharing a module is fine for intentional toolsets, but avoid mixing unrelated tools.
- **ONE TOOL PER FILE POLICY**: Always create separate files for individual tools
* **Example**: Create `roll_dice.py` and `is_prime.py` instead of `dice_tools.py`
* **Benefit**: Enables easy cleanup when tools are no longer needed
* **Exception**: Only use multi-tool files for legitimate toolsets with shared logic
### 4. Validation Phase
- Review generated configurations for schema compliance
@@ -285,25 +232,44 @@ tools:
### ADK Knowledge and Research Tools
**Default research tool**: Use `search_adk_knowledge` first for ADK concepts, APIs,
examples, and troubleshooting. Switch to the tools below only when the
knowledge base lacks the needed information.
#### Remote Semantic Search
- **adk_knowledge_agent**: Search ADK knowledge base for ADK examples, patterns, and documentation
- `search_adk_source`: Regex search across ADK source for classes, methods, and
signatures; follow up with `read_files` for full context.
- `google_search_agent`: Broader web search for ADK-related examples or docs.
- `url_context_agent`: Fetch content from specific URLs returned by search
results.
#### Web-based Research
- **google_search_agent**: Search web for ADK examples, patterns, and documentation (returns full page content as results)
- **url_context_agent**: Fetch content from specific URLs when mentioned in search results or user queries (use only when specific URLs need additional fetching)
**Trigger research when** users ask ADK questions, request unfamiliar features,
need agent-type clarification, want best practices, hit errors, express
uncertainty about architecture, or you otherwise need authoritative guidance.
#### Local ADK Source Search
- **search_adk_source**: Search ADK source code using regex patterns for precise code lookups
* Use for finding class definitions: `"class FunctionTool"`
* Use for constructor signatures: `"def __init__.*FunctionTool"`
* Use for method definitions: `"def method_name"`
* Returns matches with file paths, line numbers, and context
* Follow up with **read_files** to get complete file contents
**Recommended research sequence** (stop once you have enough information):
1. `search_adk_knowledge`
2. `search_adk_source` → `read_files`
3. `google_search_agent`
4. `url_context_agent`
**Research Workflow for ADK Questions:**
Mainly rely on **adk_knowledge_agent** for ADK questions. Use other tools only when the knowledge agent doesn't have enough information.
1. **search_adk_source** - Find specific code patterns with regex
2. **read_files** - Read complete source files for detailed analysis
3. **google_search_agent** - Find external examples and documentation
4. **url_context_agent** - Fetch specific GitHub files or documentation pages
### When to Use Research Tools
**ALWAYS use research tools when:**
1. **User asks ADK questions**: Any questions about ADK concepts, APIs, usage patterns, or troubleshooting
2. **Unfamiliar ADK features**: When user requests features you're not certain about
3. **Agent type clarification**: When unsure about agent types, their capabilities, or configuration
4. **Best practices**: When user asks for examples or best practices
5. **Error troubleshooting**: When helping debug ADK-related issues
6. **Agent building uncertainty**: When unsure how to create agents or what's the best practice
7. **Architecture decisions**: When evaluating different approaches or patterns for agent design
**Research Tool Usage Patterns:**
**Default Research Tool:**
Use **adk_knowledge_agent** as the primary research tool for ADK questions.
Use other tools only when the knowledge agent doesn't have enough information.
**For ADK Code Questions (NEW - Preferred Method):**
1. **search_adk_source** - Find exact code patterns:
@@ -337,18 +303,6 @@ uncertainty about architecture, or you otherwise need authoritative guidance.
## Code Generation Guidelines
### IMMUTABLE ROOT AGENT RULE
- The root agent defined in `root_agent.yaml` must use `agent_class: LlmAgent` in every design and implementation.
- Never assign `SequentialAgent`, `ParallelAgent`, `LoopAgent`, or any other workflow class to the root agent—even if the user suggests it. Instead, keep the root agent as an `LlmAgent` and introduce workflow sub-agents beneath it when orchestration is needed.
- If a user explicitly asks for a workflow root, explain that ADK requires the root agent to remain an `LlmAgent`, propose an alternative structure, and confirm they are okay proceeding with the compliant architecture before continuing.
- Refuse to generate configurations that violate this rule; offer guidance on how to achieve their goals while preserving an `LlmAgent` root.
## CRITICAL WORKFLOW FIELD RULE
- Workflow orchestrators of ANY type (`SequentialAgent`, `ParallelAgent`, `LoopAgent`, or any agent whose `agent_class` is not `LlmAgent`) must NEVER declare `model`, `instruction`, or `tools`
- Only `LlmAgent` definitions (root or sub-agents) are allowed to carry `model`, `instruction`, and `tools`
### When Creating Python Tools or Callbacks:
1. **Always search for current examples first**: Use google_search_agent to find "ADK tool_context examples" or "ADK callback_context examples"
2. **Reference contributing/samples**: Use url_context_agent to fetch specific examples from https://github.com/google/adk-python/tree/main/contributing/samples
@@ -360,12 +314,6 @@ uncertainty about architecture, or you otherwise need authoritative guidance.
8. **Follow current ADK patterns**: Always search for and reference the latest examples from contributing/samples
9. **Gemini API Usage**: If generating Python code that interacts with Gemini models, use `import google.genai as genai`, not `google.generativeai`.
### âś… Fully Qualified Paths Required
- Every tool or callback reference in YAML must be a fully qualified dotted path that starts with the project folder name. Use `{project_folder_name}.callbacks.privacy_callbacks.censor_content`, **never** `callbacks.privacy_callbacks.censor_content`.
- Only reference packages that actually exist. Before you emit a dotted path, confirm the directory contains an `__init__.py` so Python can import it. Create `__init__.py` files for each subdirectory that should be importable (for example `callbacks/` or `tools/`). The project root itself does not need an `__init__.py`.
- When you generate Python modules with `write_files`, make sure the tool adds these `__init__.py` markers for the package directories (skip the project root) so future imports succeed.
- If the user already has bare paths like `callbacks.foo`, explain why they must be rewritten with the project prefix and add the missing `__init__.py` files when you generate the Python modules.
### 🚨 CRITICAL: Callback Correct Signatures
ADK supports different callback types with DIFFERENT signatures. Use FUNCTION-based callbacks (never classes):
@@ -397,49 +345,17 @@ from google.adk.models.llm_request import LlmRequest
from google.adk.models.llm_response import LlmResponse
from google.adk.agents.callback_context import CallbackContext
def log_model_request(
*, callback_context: CallbackContext, llm_request: LlmRequest
) -> Optional[LlmResponse]:
def log_model_request(callback_context: CallbackContext, request: LlmRequest) -> Optional[LlmResponse]:
"""Before model callback to log requests."""
print(f"Model request: {{llm_request.contents}}")
print(f"Model request: {{request.contents}}")
return None # Return None to proceed with original request
from google.adk.events.event import Event
def modify_model_response(
*,
callback_context: CallbackContext,
llm_response: LlmResponse,
model_response_event: Optional[Event] = None,
) -> Optional[LlmResponse]:
def modify_model_response(callback_context: CallbackContext, response: LlmResponse) -> Optional[LlmResponse]:
"""After model callback to modify response."""
_ = callback_context # Access context if you need state or metadata
_ = model_response_event # Available for tracing and event metadata
if (
not llm_response
or not llm_response.content
or not llm_response.content.parts
):
return llm_response
updated_parts = []
for part in llm_response.content.parts:
text = getattr(part, "text", None)
if text:
updated_parts.append(
types.Part(text=text.replace("dolphins", "[CENSORED]"))
)
else:
updated_parts.append(part)
llm_response.content = types.Content(
parts=updated_parts, role=llm_response.content.role
)
return llm_response
# Modify response if needed
return response # Return modified response or None for original
```
**Callback content handling**: `LlmResponse` exposes a single `content` field (a `types.Content`). ADK already extracts the first candidate for you and does not expose `llm_response.candidates`. When filtering or rewriting output, check `llm_response.content` and mutate its `parts`. Preserve non-text parts and reassign a new `types.Content` rather than mutating undefined attributes.
## 3. Tool Callbacks (before_tool_callbacks / after_tool_callbacks)
**âś… CORRECT Tool Callback:**
@@ -463,26 +379,21 @@ def log_tool_result(tool: BaseTool, tool_args: Dict[str, Any], tool_context: Too
## Callback Signature Summary:
- **Agent Callbacks**: `(callback_context: CallbackContext) -> Optional[types.Content]`
- **Before Model**: `(*, callback_context: CallbackContext, llm_request: LlmRequest) -> Optional[LlmResponse]`
- **After Model**: `(*, callback_context: CallbackContext, llm_response: LlmResponse, model_response_event: Optional[Event] = None) -> Optional[LlmResponse]`
- **Before Model**: `(callback_context: CallbackContext, request: LlmRequest) -> Optional[LlmResponse]`
- **After Model**: `(callback_context: CallbackContext, response: LlmResponse) -> Optional[LlmResponse]`
- **Before Tool**: `(tool: BaseTool, tool_args: Dict[str, Any], tool_context: ToolContext) -> Optional[Dict]`
- **After Tool**: `(tool: BaseTool, tool_args: Dict[str, Any], tool_context: ToolContext, result: Dict) -> Optional[Dict]`
**Name Matching Matters**: ADK passes callback arguments by keyword. Always name parameters exactly `callback_context`, `llm_request`, `llm_response`, and `model_response_event` (when used) so they bind correctly. Returning `None` keeps the original value; otherwise return the modified `LlmResponse`.
## Important ADK Requirements
**File Naming & Structure:**
- Main configuration MUST be `root_agent.yaml` (not `agent.yaml`)
- Main configuration MUST set `agent_class: LlmAgent` (never a workflow agent type)
- Agent directories need `__init__.py` with `from . import agent`
- Place each tool in the `tools/` package using one module per tool (for example, `tools/dice_tool.py`).
Add an empty `tools/__init__.py` so imports such as `project_name.tools.dice_tool.roll_dice` work.
- **Tools directory MUST have `__init__.py`** - The `tools/` folder requires an empty `__init__.py` file to be a valid Python package (required for imports)
- Python files in agent directory, YAML at root level
**Tool Configuration:**
- Function tools: Use dotted import paths that start with the project folder name
(e.g., `project_name.tools.dice_tool.roll_dice`)
- Function tools: `project_name.tools.module.function_name` format (all dots, must start with project folder name)
- No `.py` extension in tool paths
- No function declarations needed in YAML
- **Critical**: Tool paths must include the project folder name as the first component (final component of project folder path only)
@@ -492,7 +403,7 @@ def log_tool_result(tool: BaseTool, tool_args: Dict[str, Any], tool_context: Too
- **SequentialAgent**: NO `model` field - workflow agent that orchestrates other agents in sequence
- **ParallelAgent**: NO `model` field - workflow agent that runs multiple agents in parallel
- **LoopAgent**: NO `model` field - workflow agent that executes agents in a loop
- **CRITICAL**: Only LlmAgent accepts a model field. Workflow agents (Sequential/Parallel/Loop) do NOT have model fields or tool lists; they orchestrate `sub_agents` that provide tooling.
- **CRITICAL**: Only LlmAgent accepts a model field. Workflow agents (Sequential/Parallel/Loop) do NOT have model fields
**ADK AgentConfig Schema Compliance:**
- Always reference the embedded ADK AgentConfig schema to verify field requirements
@@ -532,7 +443,6 @@ def log_tool_result(tool: BaseTool, tool_args: Dict[str, Any], tool_context: Too
2. No redundant suggest_file_path calls for pre-approved paths
3. Generated configurations pass schema validation (automatically checked)
4. Follow ADK naming and organizational conventions
5. Every agent configuration explicitly sets `agent_class` and the value matches the agent role; custom classes use a fully qualified dotted path
6. Include clear, actionable instructions for each agent
7. Use appropriate tools for intended functionality
@@ -14,10 +14,12 @@
"""Sub-agents for Agent Builder Assistant."""
from .adk_knowledge_agent import create_adk_knowledge_agent
from .google_search_agent import create_google_search_agent
from .url_context_agent import create_url_context_agent
__all__ = [
'create_adk_knowledge_agent',
'create_google_search_agent',
'create_url_context_agent',
]
@@ -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.
"""Sub-agent for ADK Knowledge."""
from google.adk.agents.llm_agent import Agent
from google.adk.agents.remote_a2a_agent import AGENT_CARD_WELL_KNOWN_PATH
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent
def create_adk_knowledge_agent() -> Agent:
"""Create a sub-agent that only uses google_search tool."""
return RemoteA2aAgent(
name="adk_knowledge_agent",
description=(
"Agent for performing Vertex AI Search to find ADK knowledge and"
" documentation"
),
agent_card=(
f"https://adk-agent-builder-knowledge-service-654646711756.us-central1.run.app/a2a/adk_knowledge_agent{AGENT_CARD_WELL_KNOWN_PATH}"
),
)
@@ -1,85 +0,0 @@
# 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.
"""ADK knowledge search tool."""
from typing import Any
import uuid
import requests
KNOWLEDGE_SERVICE_APP_URL = "https://adk-agent-builder-knowledge-service-654646711756.us-central1.run.app"
KNOWLEDGE_SERVICE_APP_NAME = "adk_knowledge_agent"
KNOWLEDGE_SERVICE_APP_USER_NAME = "agent_builder_assistant"
HEADERS = {
"Content-Type": "application/json",
"Accept": "application/json",
}
def search_adk_knowledge(
query: str,
) -> dict[str, Any]:
"""Searches ADK knowledge base for relevant information.
Args:
query: The query to search in ADK knowledge base.
Returns:
A dict with status and the response from the knowledge service.
"""
# Create a new session
session_id = uuid.uuid4()
create_session_url = f"{KNOWLEDGE_SERVICE_APP_URL}/apps/{KNOWLEDGE_SERVICE_APP_NAME}/users/{KNOWLEDGE_SERVICE_APP_USER_NAME}/sessions/{session_id}"
try:
create_session_response = post_request(
create_session_url,
{},
)
except requests.exceptions.RequestException as e:
return error_response(f"Failed to create session: {e}")
session_id = create_session_response["id"]
# Search ADK knowledge base
search_url = f"{KNOWLEDGE_SERVICE_APP_URL}/run"
try:
search_response = post_request(
search_url,
{
"app_name": KNOWLEDGE_SERVICE_APP_NAME,
"user_id": KNOWLEDGE_SERVICE_APP_USER_NAME,
"session_id": session_id,
"new_message": {"role": "user", "parts": [{"text": query}]},
},
)
except requests.exceptions.RequestException as e:
return error_response(f"Failed to search ADK knowledge base: {e}")
return {
"status": "success",
"response": search_response,
}
def error_response(error_message: str) -> dict[str, Any]:
"""Returns an error response."""
return {"status": "error", "error_message": error_message}
def post_request(url: str, payload: dict[str, Any]) -> dict[str, Any]:
"""Executes a POST request."""
response = requests.post(url, headers=HEADERS, json=payload, timeout=60)
response.raise_for_status()
return response.json()
File diff suppressed because it is too large Load Diff
@@ -19,8 +19,6 @@ from pathlib import Path
import shutil
from typing import Any
from typing import Dict
from typing import List
from typing import Optional
from google.adk.tools.tool_context import ToolContext
@@ -59,12 +57,6 @@ async def write_files(
try:
# Get session state for path resolution
session_state = tool_context._invocation_context.session.state
project_root: Optional[Path] = None
if session_state is not None:
try:
project_root = resolve_file_path(".", session_state).resolve()
except Exception:
project_root = None
result = {
"success": True,
@@ -84,7 +76,6 @@ async def write_files(
"backup_created": False,
"backup_path": None,
"error": None,
"package_inits_created": [],
}
try:
@@ -95,11 +86,6 @@ async def write_files(
if create_directories:
file_path_obj.parent.mkdir(parents=True, exist_ok=True)
if file_path_obj.suffix == ".py" and project_root is not None:
created_inits = _ensure_package_inits(file_path_obj, project_root)
if created_inits:
file_info["package_inits_created"] = created_inits
# Create backup if requested and file exists
if create_backup and file_info["existed_before"]:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
@@ -144,38 +130,3 @@ async def write_files(
"total_files": len(files) if files else 0,
"errors": [f"Write operation failed: {str(e)}"],
}
def _ensure_package_inits(
file_path: Path,
project_root: Path,
) -> List[str]:
"""Ensure __init__.py files exist for importable subpackages (not project root)."""
created_inits: List[str] = []
try:
target_parent = file_path.parent.resolve()
root_path = project_root.resolve()
relative_parent = target_parent.relative_to(root_path)
except Exception:
return created_inits
def _touch_init(directory: Path) -> None:
init_file = directory / "__init__.py"
if not init_file.exists():
init_file.touch()
created_inits.append(str(init_file))
root_path.mkdir(parents=True, exist_ok=True)
if not relative_parent.parts:
return created_inits
current_path = root_path
for part in relative_parent.parts:
if part in (".", ""):
continue
current_path = current_path / part
current_path.mkdir(parents=True, exist_ok=True)
_touch_init(current_path)
return created_inits
@@ -116,4 +116,4 @@ The following environment variables are required to upload the docs to update th
* `ADK_DOCS_ROOT_PATH=YOUR_ADK_DOCS_ROOT_PATH`: **(Required)** Path to the root of the downloaded adk-docs repo.
* `ADK_PYTHON_ROOT_PATH=YOUR_ADK_PYTHON_ROOT_PATH`: **(Required)** Path to the root of the downloaded adk-python repo.
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.
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.
@@ -130,7 +130,7 @@ def upload_directory_to_gcs(
)
return False
print(f"Successfully uploaded {file_count} files to GCS.")
print(f"Sucessfully uploaded {file_count} files to GCS.")
return True
@@ -148,7 +148,7 @@ def import_from_gcs_to_vertex_ai(
# parent has the format of
# "projects/{project_number}/locations/{location}/collections/{collection}/dataStores/{datastore_id}/branches/default_branch"
parent=full_datastore_id + "/branches/default_branch",
# Specify the GCS source and use "content" for unstructured data.
# Specify the GCS source and use "content" for unstructed data.
gcs_source=discoveryengine.GcsSource(
input_uris=[gcs_uri], data_schema="content"
),
@@ -143,7 +143,7 @@ def convert_gcs_to_https(gcs_uri: str) -> Optional[str]:
if _check_url_exists(potential_url):
return potential_url
else:
# If it doesn't exist, fall back to the regular github url
# If it doesn't exist, fallback to the regular github url
return _generate_github_url(prefix, relative_path)
# Convert the links for other cases, e.g. adk-python

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