Compare commits

...

552 Commits

Author SHA1 Message Date
Liang Wu cec59db3df Merge branch 'main' into v1.25.0 2026-02-11 21:19:38 -08:00
Kathy Wu 9f7d5b3f14 feat: Add load_skill_from_dir() method
This allows users to load skills from a directory and pass it into the SkillToolset constructor.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 868929937
2026-02-11 18:10:54 -08:00
Xuan Yang b7f9110b52 chore: Introduce a unified Context
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 868890552
2026-02-11 16:16:24 -08:00
Yifan 8cd22fb746 chore(version): Bump version and update changelog for 1.25.0
Merge https://github.com/google/adk-python/pull/4455

**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._

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4455 from google:release/candidate f660ec82ff4140ef1deea95182e6e0cc62100f89
PiperOrigin-RevId: 868877872
2026-02-11 15:46:09 -08:00
George Weale 079f7a38be fix: Support escaped curly braces in instruction templates
Close #3527

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 868875061
2026-02-11 15:38:53 -08:00
Yifan Wang ef471b8ef9 revise changelog 2026-02-11 14:37:55 -08:00
Google Team Member 34da2d5b26 feat: enable dependency injection for agent loader in FastAPI app gen
This enables to re-use the ADK web interface in other contexts more easily.
For example, when having an own run-time the web interface can be exposed
for visualization during development.

Also add documentation for function.

PiperOrigin-RevId: 868848338
2026-02-11 14:35:35 -08:00
Yifan Wang eb37ba672a remove experimental log, and change UI to web 2026-02-11 14:34:39 -08:00
Yifan Wang 79cb1db75f remove unnecessary chage logs 2026-02-11 14:29:29 -08:00
Yifan Wang ba55849f8e chore(version): Bump version and update changelog for 1.25.0 2026-02-11 14:23:58 -08:00
Leon Ziyang Zhang bcbfeba953 feat: pass trace context in MCP tool call's _meta field with Otel propagator
PiperOrigin-RevId: 868841079
2026-02-11 14:18:22 -08:00
Liang Wu 9dccd6a692 feat(conformance): read report's version info from the server
Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 868837301
2026-02-11 14:10:57 -08:00
Wei Sun (Jack) 38b4869c41 chore(ci): migrate release pipeline from release-please App to GitHub Actions
Remove the release-please GitHub App config files and add an Actions-based
release pipeline with candidate branch strategy. This includes workflows for
cutting releases, running release-please, finalizing releases, publishing to
PyPI, and cherry-picking fixes to release candidates.

Co-authored-by: Wei Sun (Jack) <weisun@google.com>
PiperOrigin-RevId: 868825704
2026-02-11 13:47:41 -08:00
Hiroaki Sano 657acfadbb docs: Add PostgreSQL session storage sample and documentation
Merge https://github.com/google/adk-python/pull/3926

### Link to Issue or Description of Change

**1. Link to an existing issue (if applicable):**

- Related: #3916

**2. Or, if no issue exists, describe the change:**

**Problem:**
While `DatabaseSessionService` already supports PostgreSQL through SQLAlchemy, there is no documentation or sample code showing users how to configure and use it.

**Solution:**
Add a comprehensive sample under `contributing/samples/postgres_session_service/` that demonstrates:
- How to configure `DatabaseSessionService` with PostgreSQL
- The auto-generated database schema (sessions, events, app_states, user_states tables)
- Connection URL format and configuration options
- A working sample agent with session persistence

### Testing Plan

**Unit Tests:**

- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

This is a documentation-only change (new sample), so no new unit tests are required. Existing tests continue to pass.

**Manual End-to-End (E2E) Tests:**

Tested locally with the following steps:

1. Started PostgreSQL using `docker compose up -d`
2. Set environment variables:

```bash
export POSTGRES_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/adk_sessions
export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)
export GOOGLE_CLOUD_LOCATION=us-central1
export GOOGLE_GENAI_USE_VERTEXAI=true
```
3. Ran `pip install google-adk asyncpg greenlet` to install the required packages
4. Ran `python main.py` - session created successfully
5. Ran `python main.py` again - previous session resumed with event history
6. Verified tables and rows created in PostgreSQL (sessions, events, app_states, user_states)

### Checklist

- [x] I have read the https://github.com/google/adk-python/blob/main/CONTRIBUTING.md document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.

### Additional context

This PR adds documentation and a working sample for an already-supported feature. The DatabaseSessionService class already handles PostgreSQL through its DynamicJSON type decorator which uses JSONB for PostgreSQL.

Files added:
- contributing/samples/postgres_session_service/README.md - Comprehensive guide
- contributing/samples/postgres_session_service/agent.py - Sample agent
- contributing/samples/postgres_session_service/main.py - Usage example
- contributing/samples/postgres_session_service/compose.yml - Local PostgreSQL setup
- contributing/samples/postgres_session_service/\_\_init\_\_.py - Package init

Co-authored-by: Liang Wu <wuliang@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3926 from hiroakis:feat-support-pg-for-conversation a5279d4fb2a63699f384c670928d77d882c25a25
PiperOrigin-RevId: 868816317
2026-02-11 13:25:52 -08:00
Liang Wu 61c329f8ce ci: match the environment with internal ones for pyink/isort/unittest
Previously submitted change is causing [Pyink error](https://github.com/google/adk-python/actions/runs/21884351396/job/63176122118) in repo because Pyink recently updated to 25.12.0.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 868806575
2026-02-11 13:01:32 -08:00
Anmol Jaiswal 758d337c76 fix(sessions): use async iteration for VertexAiSessionService.list_sessions pagination
Merge https://github.com/google/adk-python/pull/4435

### Link to Issue or Description of Change

- Closes: #4302

**Problem:**

`VertexAiSessionService.list_sessions()` only returns the first ~100 sessions. The `sessions_iterator` from `api_client.agent_engines.sessions.list()` is an `AsyncPager` — it implements `__aiter__`/`__anext__` for fetching subsequent pages, but the code uses a plain `for` loop which only calls `__iter__`/`__next__`, so it never fetches beyond the first page.

**Solution:**

Changed `for api_session in sessions_iterator` to `async for api_session in sessions_iterator` so the `AsyncPager` actually paginates. Updated the test mock to return an `AsyncIterableList` (supports both sync and async iteration) instead of a bare list, so the tests properly simulate real `AsyncPager` behaviour.

### Testing Plan

**Unit Tests:**

```
$ pytest tests/unittests/sessions/
115 passed, 1 warning in 2.25s
```

The existing `test_list_sessions`, `test_list_sessions_with_pagination`, and `test_list_sessions_all_users` all continue to pass with the updated mock.

Co-authored-by: Liang Wu <wuliang@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4435 from anmolg1997:fix/vertex-ai-session-service-pagination 14c71b607ecbf2215f4b9ba6eb4b0ff6b9eaf740
PiperOrigin-RevId: 868466166
2026-02-10 21:18:51 -08:00
Google Team Member 3cf43e3842 feat: Enhance google credentials config to support externally passed access token
PiperOrigin-RevId: 868390961
2026-02-10 17:21:38 -08:00
Kathy Wu 4aa475145f fix: Fix event loop closed bug in McpSessionManager
Sessions were being erroneously cached and reused across different asyncio event loops, causing "Event loop is closed" in environments with transient loops. This updates the session caching to be loop-aware: before reusing a cached session, check that the stored loop matches the current loop. Also, if session is disconnected and loops do not match, discard the cached entry without calling aclose().

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 868380746
2026-02-10 16:50:53 -08:00
Xiang (Sean) Zhou 7110336788 refactor: Replace check of instance for LlmAgent with hasAttribute check
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 868370272
2026-02-10 16:27:20 -08:00
Google Team Member 0abf4cd2c7 feat: Add a demo simple prompt optimizer for the optimization interface
PiperOrigin-RevId: 868367793
2026-02-10 16:21:11 -08:00
Edwin Kim 40c15d0595 feat(cli): Add --auto_create_session flag to adk api_server CLI
Merge https://github.com/google/adk-python/pull/4288

**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: #4274

**2. Or, if no issue exists, describe the change:**

N/A - Issue exists

### 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:**

- [X] I have added or updated unit tests for my change.
- [X] All unit tests pass locally.

$ pytest tests/unittests/cli/ -v

============================= test session starts ==============================
platform darwin -- Python 3.11.14, pytest-9.0.2, pluggy-1.6.0
collected 246 items
...
====================== 246 passed, 147 warnings in 21.38s ======================

**Manual End-to-End (E2E) Tests:**

1. Verify CLI flag is recognized:
$ adk api_server --help | grep auto_create_session --auto_create_session
Automatically create a session if it doesn't exist when calling /run.

2. Start server with flag enabled:
$ adk api_server --auto_create_session

3. Test /run endpoint without pre-creating session:
$ curl -X POST http://localhost:8000/run \
  -H "Content-Type: application/json" \
  -d '{"app_name": "my_agent", "user_id": "user1", "session_id": "new_session", "new_message": {"role": "user", "parts": [{"text": "Hello"}]}}'

Expected: Session auto-created, request succeeds (no 404 error).

### Checklist

- [X] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [X] I have performed a self-review of my own code.
- [X] I have commented my code, particularly in hard-to-understand areas.
- [X] I have added tests that prove my fix is effective or that my feature works.
- [X] New and existing unit tests pass locally with my changes.
- [X] I have manually tested my changes end-to-end.
- [X] Any dependent changes have been merged and published in downstream modules.

### Additional context
This PR exposes the existing Runner.auto_create_session functionality (added in commit 8e69a58 / ADK v1.23.0) through the adk api_server CLI command.

Files changed (3 files, ~15 lines):

src/google/adk/cli/cli_tools_click.py - Add --auto_create_session CLI option
src/google/adk/cli/fast_api.py - Pass parameter through get_fast_api_app()
src/google/adk/cli/adk_web_server.py - Store and use in _create_runner()

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4288 from ekimcodes:main 3c8d299a88b21789431dbda488befba7ee3ace81
PiperOrigin-RevId: 868361303
2026-02-10 16:06:01 -08:00
Xuan Yang 2010569010 fix: Preserve thought_signature in function call conversions for interactions API integration
Related: https://github.com/google/adk-python/issues/4311

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 868340444
2026-02-10 15:14:18 -08:00
Google Team Member 7af1858f46 feat: Update agent simulator by improving prompts and add environment data
PiperOrigin-RevId: 868324749
2026-02-10 14:37:03 -08:00
Sasha Sobran e6da417292 fix: propagate grounding and citation metadata in streaming responses
Co-authored-by: Sasha Sobran <asobran@google.com>
PiperOrigin-RevId: 868324488
2026-02-10 14:36:21 -08:00
Didier Durand 6ee5126d1c docs: fixing a typo
Merge https://github.com/google/adk-python/pull/3975

### Link to Issue or Description of Change

Fixing various typos: see commit diffs for details

**1. Link to an existing issue (if applicable):**

- Closes: N/A
- Related: N/A

**2. Or, if no issue exists, describe the change:**

Fixing various typos: see commit diffs for details

**Problem:**

Improve quality of repo

**Solution:**
Pull this P/R

### Testing Plan

N/A
**Unit Tests:**

- [N/A] I have added or updated unit tests for my change.
- [X] All unit tests pass locally.

**Manual End-to-End (E2E) Tests:**

N/A

### Checklist

- [X] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [X] I have performed a self-review of my own code.
- [N/A] I have commented my code, particularly in hard-to-understand areas.
- [N/A] I have added tests that prove my fix is effective or that my feature works.
- [X] New and existing unit tests pass locally with my changes.
- [N/A] I have manually tested my changes end-to-end.
- [N/A] Any dependent changes have been merged and published in downstream modules.

### Additional context

N/A

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3975 from didier-durand:fix-typos-b ca1cba4e7afe99bb60efffb4de79a2bfe8522ea8
PiperOrigin-RevId: 868308215
2026-02-10 14:01:58 -08:00
George Weale a88e864755 fix: Add post-invocation token-threshold compaction with event retention
Adds optional token_limit and event_retention_size fields to EventsCompactionConfig. When the latest prompt token count meets/exceeds the threshold, ADK compacts older raw events after the invocation and keeps the last N events un-compacted. Updates prompt history building to apply compaction ranges correctly so retained events remain visible.

Close #4146

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 868297968
2026-02-10 13:38:28 -08:00
Liang Wu 25ec2c6b61 feat(web): Add /health and /version endpoints to ADK web server
These endpoints provide basic health checks and version information for the running ADK server, including the ADK version and Python runtime details. The version information will be used to generate ADK conformance test report.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 868283421
2026-02-10 13:07:21 -08:00
Salman Chishti 2f0fe97729 ci: Upgrade GitHub Actions for Node 24 compatibility
Merge https://github.com/google/adk-python/pull/4426

## Summary

Upgrade GitHub Actions to their latest versions to ensure compatibility with Node 24, as Node 20 will reach end-of-life in April 2026.

## Changes

| Action | Old Version(s) | New Version | Release | Files |
|--------|---------------|-------------|---------|-------|
| `actions/checkout` | [`v4`](https://github.com/actions/checkout/releases/tag/v4) | [`v6`](https://github.com/actions/checkout/releases/tag/v6) | [Release](https://github.com/actions/checkout/releases/tag/v6) | mypy-new-errors.yml, mypy.yml |
| `actions/setup-python` | [`v5`](https://github.com/actions/setup-python/releases/tag/v5) | [`v6`](https://github.com/actions/setup-python/releases/tag/v6) | [Release](https://github.com/actions/setup-python/releases/tag/v6) | mypy-new-errors.yml, mypy.yml |

## Context

Per [GitHub's announcement](https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/), Node 20 is being deprecated and runners will begin using Node 24 by default starting March 4th, 2026.

### Why this matters

- **Node 20 EOL**: April 2026
- **Node 24 default**: March 4th, 2026
- **Action**: Update to latest action versions that support Node 24

### Security Note

Actions that were previously pinned to commit SHAs remain pinned to SHAs (updated to the latest release SHA) to maintain the security benefits of immutable references.

### Testing

These changes only affect CI/CD workflow configurations and should not impact application functionality. The workflows should be tested by running them on a branch before merging.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4426 from salmanmkc:upgrade-github-actions-node24 a574f92c72502ae60531163da60f7820e01380f3
PiperOrigin-RevId: 868281419
2026-02-10 13:02:24 -08:00
Salman Chishti f5702d70bf ci: Upgrade GitHub Actions to latest versions
Merge https://github.com/google/adk-python/pull/4427

## Summary

Upgrade GitHub Actions to their latest versions for improved features, bug fixes, and security updates.

## Changes

| Action | Old Version(s) | New Version | Release | Files |
|--------|---------------|-------------|---------|-------|
| `astral-sh/setup-uv` | [`v1`](https://github.com/astral-sh/setup-uv/releases/tag/v1), [`v5`](https://github.com/astral-sh/setup-uv/releases/tag/v5), [`v6`](https://github.com/astral-sh/setup-uv/releases/tag/v6) | [`v7`](https://github.com/astral-sh/setup-uv/releases/tag/v7) | [Release](https://github.com/astral-sh/setup-uv/releases/tag/v7) | mypy-new-errors.yml, mypy.yml, python-unit-tests.yml |
| `webfactory/ssh-agent` | [`v0.9.0`](https://github.com/webfactory/ssh-agent/releases/tag/v0.9.0) | [`v0.9.1`](https://github.com/webfactory/ssh-agent/releases/tag/v0.9.1) | [Release](https://github.com/webfactory/ssh-agent/releases/tag/v0) | analyze-releases-for-adk-docs-updates.yml |

## Why upgrade?

Keeping GitHub Actions up to date ensures:
- **Security**: Latest security patches and fixes
- **Features**: Access to new functionality and improvements
- **Compatibility**: Better support for current GitHub features
- **Performance**: Optimizations and efficiency improvements

### Security Note

Actions that were previously pinned to commit SHAs remain pinned to SHAs (updated to the latest release SHA) to maintain the security benefits of immutable references.

### Testing

These changes only affect CI/CD workflow configurations and should not impact application functionality. The workflows should be tested by running them on a branch before merging.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4427 from salmanmkc:upgrade-github-actions-node24-general 4aacbae5378233559880ff155e4f478e484c694b
PiperOrigin-RevId: 868263909
2026-02-10 12:20:03 -08:00
George Weale 59e88972ae feat: add add_events_to_memory facade for event-delta
Adds BaseMemoryService.add_events_to_memory(session, events=..., custom_metadata=...) and CallbackContext.add_events_to_memory(events=..., custom_metadata=...) so callers can add memories from an explicit subset of ADK events.

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 868261578
2026-02-10 12:14:52 -08:00
Google Team Member de79bf12b5 feat: log exception details before re-raising in MCP session execution
Adds a logger.exception call to capture traceback and error details when an exception occurs during the execution of a coroutine within an MCP session, before re-raising it as a ConnectionError.

PiperOrigin-RevId: 868253547
2026-02-10 11:56:38 -08:00
Didier Durand 80ff067c6b docs: fixing typo in multiple files
Merge https://github.com/google/adk-python/pull/3944

### Link to Issue or Description of Change

**1. Link to an existing issue (if applicable):** N/A

**2. Or, if no issue exists, describe the change:** fixing various typos in multiple files: see commit diffs for details

**Problem:**

Discovered typos while reading ADK repo

**Solution:**

Submitted this PR to fix them

### Testing Plan

N/A: changes only in comments, .md and docstrings.

**Unit Tests:**

- [N/A ] I have added or updated unit tests for my change.
- [X] All unit tests pass locally.

_Please include a summary of passed `pytest` results._

**Manual End-to-End (E2E) Tests:**

N/A

### Checklist

- [X] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [X] I have performed a self-review of my own code.
- [N/A] I have commented my code, particularly in hard-to-understand areas.
- [N/A] I have added tests that prove my fix is effective or that my feature works.
- [X] New and existing unit tests pass locally with my changes.
- [N/A] I have manually tested my changes end-to-end.
- [N/A] Any dependent changes have been merged and published in downstream modules.

### Additional context

N/A

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3944 from didier-durand:fix-typos-a 02378a488d9a87ac9b6b7397fe9ad7c393faf16a
PiperOrigin-RevId: 868245940
2026-02-10 11:38:22 -08:00
sarojrout e0b9712a49 fix: Add endpoints to get/list artifact version metadata
This change introduces new FastAPI endpoints in adk_web_server.py and corresponding client methods in adk_web_server_client.py to allow fetching metadata for artifact versions without downloading the artifact content

Close #3710

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 868217569
2026-02-10 10:40:54 -08:00
George Weale 7c7d25a4a6 fix: Support escaped curly braces in instruction templates
Close #3527

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 868199186
2026-02-10 10:04:39 -08:00
Kathy Wu ec660ed4f0 chore: Add experimental tag to SkillToolset
Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 867816959
2026-02-09 16:07:35 -08:00
Filipe Caixeta 19b607684f fix: Strip timezone for PostgreSQL timestamps in DatabaseSessionService
Merge https://github.com/google/adk-python/pull/4365

## Summary
- Fixes `DataError` when using PostgreSQL with `asyncpg` for session storage
- PostgreSQL's default `TIMESTAMP` type is `WITHOUT TIME ZONE`, which cannot accept timezone-aware datetime objects
- The existing code handled this for SQLite but not PostgreSQL - this fix applies the same timezone stripping

## Error
When creating a session with PostgreSQL + asyncpg, the following error occurs:

```
sqlalchemy.dialects.postgresql.asyncpg.Error: <class 'asyncpg.exceptions.DataError'>:
invalid input for query argument $5: datetime.datetime(2026, 2, 3, 21, 32, 50, 353909,
tzinfo=datetime.timezone.utc) (can't subtract offset-naive and offset-aware datetimes)
```

During the INSERT:
```sql
INSERT INTO sessions (app_name, user_id, id, state, create_time, update_time)
VALUES ($1, $2, $3, $4, $5, $6)
```

Where `$5` and `$6` are timezone-aware datetimes being inserted into `TIMESTAMP WITHOUT TIME ZONE` columns.

## Root Cause
Commit 1063fa53 changed from database-generated timestamps (`func.now()`) to explicit Python datetimes (`datetime.now(timezone.utc)`). The SQLite case was handled by stripping the timezone, but PostgreSQL was overlooked.

## Test plan
- [x] Verified fix resolves the error when creating sessions with PostgreSQL + asyncpg
- [ ] Existing unit tests pass

Fixes regression from #1733

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4365 from filipecaixeta:fix-postgresql-timestamp-timezone 9d788ba99e7167a53962d93e59a80f78af091ca9
PiperOrigin-RevId: 867800330
2026-02-09 15:27:42 -08:00
Kathy Wu 8d0279251c feat: Add SkillToolset to adk
Currently supports load skill and load skill resource, scripts support coming later.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 867756231
2026-02-09 13:46:49 -08:00
George Weale f50847460f fix: Per-session locking and row-level locking in DatabaseSessionService.append_event
This change introduces an in-process `asyncio.Lock` per session to serialize `append_event` calls for the same session ID within a single process. For supported database dialects (MySQL, PostgreSQL, MariaDB), it also uses `SELECT ... FOR UPDATE` to acquire row-level locks on the session, app state, and user state records, preventing race conditions across different processes or database connections. A new test case verifies that concurrent updates to stale session objects correctly merge all state changes.

Close #1049

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 867752676
2026-02-09 13:38:38 -08:00
Benson Wang 32ee07df01 fix: prompt token may be None in streaming mode
Merge https://github.com/google/adk-python/pull/3462

**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:**

**Problem:**
When using adk in streaming mode, `usage_metadata.prompt_token_count` may be `None` which will emit log
```Invalid type NoneType for attribute 'gen_ai.usage.input_tokens' value. Expected one of ['bool', 'str', 'bytes', 'int', 'float'] or a sequence of those types```

**Solution:**
Skip setting span attribute if prompt token count is None

**Unit Tests:**

- [x] All unit tests pass locally.

_Please include a summary of passed `pytest` results._

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3462 from wsa-2002:prompt-token-count-may-be-none-in-streaming-mode 94666862f70ed2577d5c55485e67f6da36a57bc6
PiperOrigin-RevId: 867693355
2026-02-09 11:24:22 -08:00
Liang Wu 43c437e38b feat(conformance): add report generation to adk conformance test command
Added `generate_report` and `report_dir` CLI args to the command.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 867689055
2026-02-09 11:15:11 -08:00
George Weale d2dba27134 fix: Pass invocation_id from /run endpoint to Runner.run_async
Close #3290

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 867684592
2026-02-09 11:15:00 -08:00
George Weale 663cb75b32 fix: Conditionally preserve function call IDs in LLM requests
Function call and response IDs generated by ADK are now preserved in the LLM request contents when the agent is using a Gemini model with `use_interactions_api` enabled

Close #4381

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 867675945
2026-02-09 10:46:55 -08:00
George Weale 64a44c2897 fix: Migrate VertexAiMemoryBankService to use the async Vertex AI client
This change updates the VertexAiMemoryBankService to utilize the asynchronous interface provided by `vertexai.Client().aio`. This involves:
-   Retrieving the async client via `_get_api_client().aio`.
-   Awaiting calls to `generate` and `retrieve`.
-   Using `async for` to iterate over the results of the `retrieve` method, as it now returns an async iterator

Close #4386

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 867675311
2026-02-09 10:45:15 -08:00
George Weale 0758f877b1 chore: remove bare excepts
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 867666149
2026-02-09 10:25:03 -08:00
George Weale fd8a9e3962 fix: Handle list values in Gemini schema sanitization
The schema sanitization utility now recursively processes list items, ensuring that properties with list values (e.g., "required") are correctly handled and not altered.

Close #4363

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 867663267
2026-02-09 10:20:08 -08:00
Dinesh Thumma 6bc70a6bab fix(mcp): used logger to log instead of print
Merge https://github.com/google/adk-python/pull/4324

**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: #4320

**2. Or, if no issue exists, describe the change:**

**Problem:**
 Was using print instead of logger for warning message

**Solution:*
Refactored

### Testing Plan

**Unit Tests:**

- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

_Please include a summary of passed `pytest` results._

**Manual End-to-End (E2E) Tests:**

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] 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._

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4324 from DineshThumma9:logger_in_mcp_session_clean 5eaa9bdc8c3c6697e75b0e876f043d496dd8ee95
PiperOrigin-RevId: 867601662
2026-02-09 07:48:36 -08:00
Wei Sun (Jack) a2e43aaf19 chore(version): Limits sphinx under 9 for docs
Co-authored-by: Wei Sun (Jack) <weisun@google.com>
PiperOrigin-RevId: 866569793
2026-02-06 12:34:07 -08:00
Kathy Wu e25227da5e feat: Add a load MCP resource tool
If the user specifies use_mcp_resources=True in their MCPToolset, the agent will be able to load resources with the load_mcp_resource_tool.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 866539602
2026-02-06 11:18:32 -08:00
Kathy Wu c7362100eb feat: Add models.py and prompt.py to adk/skills to use in skill toolset
Also redefined schemas in models.py to be pydantic.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 866270203
2026-02-05 22:06:58 -08:00
Google Team Member 483c5bab94 ADK changes
PiperOrigin-RevId: 866173091
2026-02-05 16:55:06 -08:00
Google Team Member 0b9cbd2d42 feat: Add experimental agent tool simulator
PiperOrigin-RevId: 866160711
2026-02-05 16:21:48 -08:00
Matthew Chan 781f605a1e feat: add base_url option to Gemini LLM class
PiperOrigin-RevId: 866146209
2026-02-05 15:44:00 -08:00
Kacper Jawoszek d9e8e9cf32 fix: otel_to_cloud flag help text points at Cloud Run instead of Agent Engine
Co-authored-by: Kacper Jawoszek <jawoszek@google.com>
PiperOrigin-RevId: 866122815
2026-02-05 14:49:02 -08:00
Wei Sun (Jack) 93a085ad87 chore(version): Bumps version to 1.24.1 patch
Co-authored-by: Wei Sun (Jack) <weisun@google.com>
PiperOrigin-RevId: 866107525
2026-02-05 14:13:02 -08:00
Google Team Member 6645aa07fd feat: Add experimental agent tool simulator
PiperOrigin-RevId: 866100611
2026-02-05 13:57:57 -08:00
Yifan Wang 3686a3a98f chore: update adk web files, updated eval dialog colors, and fixed a2ui component types
Co-authored-by: Yifan Wang <wanyif@google.com>
PiperOrigin-RevId: 866057812
2026-02-05 12:16:54 -08:00
Yifan Wang ae993e884f fix: adding back deprecated eval endpoint for web until we migrate
Co-authored-by: Yifan Wang <wanyif@google.com>
PiperOrigin-RevId: 866049699
2026-02-05 11:58:04 -08:00
George Weale bb89466623 chore: Improve type hints and handle None values in ADK utils
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 866025998
2026-02-05 11:04:46 -08:00
Xuan Yang adbc37fea1 feat: Add progress_callback support to MCPTool and MCPToolset
Fixes: https://github.com/google/adk-python/issues/3811

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 866025995
2026-02-05 11:04:36 -08:00
George Weale 9b112e2d13 fix: Refactor context filtering to better handle multi-turn invocations
The definition of an "invocation" for context filtering has been updated. An invocation now starts with a user message and can include multiple model turns (like the tool calls and responses) until the next user message. The filtering logic has been rewritten to identify invocation start points based on human user messages

Close #4296

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 866023290
2026-02-05 10:57:56 -08:00
Google Team Member a08bf62b95 feat(otel): add extra attributes to span generated with opentelemetry-instrumentation-google-genai
PiperOrigin-RevId: 865825792
2026-02-05 01:58:30 -08:00
Liang Wu e752bbb756 chore: Remove unused tzlocal dependency and logging
The `tzlocal` library and the logging of the local timezone were not used in the `DatabaseSessionService` logic.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 865677320
2026-02-04 18:49:55 -08:00
Wei Sun (Jack) fb941f9011 chore(version): Bump version and update changelog for 1.24.0
Co-authored-by: Wei Sun (Jack) <weisun@google.com>
PiperOrigin-RevId: 865651579
2026-02-04 17:26:50 -08:00
Yifan Wang de44bbc17c chore: update adk web
Co-authored-by: Yifan Wang <wanyif@google.com>
PiperOrigin-RevId: 865625039
2026-02-04 16:13:51 -08:00
Kathy Wu 7deffb16fd fix: pass tool context into require_confirmation function in McpTool
Aligns with the FunctionTool implementation of require_confirmation. This fixes https://github.com/google/adk-python/issues/4327.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 865566362
2026-02-04 13:55:39 -08:00
nikkie ac1401bd44 fix: Escape Click’s Wrapping in bulled lists of adk web options
Merge https://github.com/google/adk-python/pull/4338

### Link to Issue or Description of Change

**2. Or, if no issue exists, describe the change:**

**Problem:**
Click collapses intended bullet lists in the service URI options.

<img width="709" height="267" alt="image" src="https://github.com/user-attachments/assets/5f74d8a6-f343-41a4-ba6d-570ed0076932" />

**Solution:**
Add `\b` on a line by itself before the formatted block to preserve blank lines.

### Testing Plan

This is format improvement of help message, so I think there is no need to add test case.

**Unit Tests:**

- [ ] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

```
% pytest tests/unittests/cli  # Python 3.13.8
===================================== 260 passed, 140 warnings in 9.30s ======================================
```

**Manual End-to-End (E2E) Tests:**

`adk web --help`

```
  --session_service_uri TEXT      Optional. The URI of the session service. If set, ADK uses this service.

                                  If unset, ADK chooses a default session service (see
                                  --use_local_storage).
                                  - Use 'agentengine://<agent_engine>' to connect to Agent Engine
                                    sessions. <agent_engine> can either be the full qualified resource
                                    name 'projects/abc/locations/us-central1/reasoningEngines/123' or
                                    the resource id '123'.
                                  - Use 'memory://' to run with the in-memory session service.
                                  - Use 'sqlite://<path_to_sqlite_file>' to connect to a SQLite DB.
                                  - See https://docs.sqlalchemy.org/en/20/core/engines.html#backend-specific-urls
                                    for supported database URIs.
```

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4338 from ftnext:escape-wrapping-web-options-bullet-list 9466731aff293d241cc7ae5728bc3c34c5c89dd6
PiperOrigin-RevId: 865533252
2026-02-04 12:40:13 -08:00
Gabriel Bengo 3c63c2ad39 fix(docs): fix grammar and remove duplicate words in documentation and source
Merge https://github.com/google/adk-python/pull/4335

Fixed 'the the' typos and grammatical errors in README, docstrings, and sample agents.

**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: N/A
- Related: N/A

**2. Or, if no issue exists, describe the change:**

**Problem:**
While exploring the repository, I noticed a few minor writing errors that impact professional readability:
1.  **Grammar:** A subject-verb agreement error in `README.md` and `llms.txt` ("guide the agents works together").
2.  **Duplicate Words:** Several instances of stuttering typos (repeating "the the" or "but the the") in docstrings within `src/` and the `contributing/samples/` directories.

**Solution:**
I have applied the following fixes to improve documentation quality:
*   Corrected phrasing to "guide the agents to work together" in the README.
*   Removed redundant instances of "the" in `eval_metrics.py`, `spanner/settings.py`, and the sample agent docstrings.
*   **No functional code or logic was altered.**

### Testing Plan

**Unit Tests:**

- [x] All unit tests pass locally.

_Summary:_
Since this PR is strictly limited to documentation, comments, and docstrings, no new tests were required. I ran the standard test suite to ensure no syntax errors were accidentally introduced, and everything passed successfully.

**Manual End-to-End (E2E) Tests:**
N/A — This is a static documentation fix.

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [ ] I have commented my code, particularly in hard-to-understand areas. (N/A)
- [ ] I have added tests that prove my fix is effective or that my feature works. (N/A - Doc fix only)
- [x] New and existing unit tests pass locally with my changes.
- [ ] I have manually tested my changes end-to-end. (N/A)
- [x] Any dependent changes have been merged and published in downstream modules.

### Additional context

_None._

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4335 from 88448844:fix-typos-and-docs 200668dad0c216b81d7008d9d6625ac135c9006e
PiperOrigin-RevId: 865530036
2026-02-04 12:31:54 -08:00
George Weale f90adff8c5 fix: Add query parameters to /run_live for advanced run configurations
The /run_live websocket endpoint now accepts proactive_audio, enable_affective_dialog, and enable_session_resumption as query parameters. These parameters control the corresponding settings within the RunConfig used for the live session

Close #4263

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 865441673
2026-02-04 09:24:01 -08:00
Google Team Member 1de65cf314 No public description
PiperOrigin-RevId: 865138065
2026-02-03 18:26:30 -08:00
Xuan Yang 2220d885cd fix: Check will_continue for streaming function calls
Related: https://github.com/google/adk-python/issues/4311

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 865074872
2026-02-03 15:33:44 -08:00
Yifan Wang 37e6507ce4 chore: update adk_web, re-work events, and adding A2UI capabilities
Co-authored-by: Yifan Wang <wanyif@google.com>
PiperOrigin-RevId: 865027256
2026-02-03 13:42:44 -08:00
Yeesian Ng 004e15ccb7 feat: Allow passthrough of GOOGLE_CLOUD_LOCATION for AgentEngine deployments
Co-authored-by: Yeesian Ng <ysian@google.com>
PiperOrigin-RevId: 865013321
2026-02-03 13:11:45 -08:00
George Weale 574ec43a17 chore: Improve error handling for LiteLlm import in gemma_llm.py
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 865010258
2026-02-03 13:04:27 -08:00
Liang Wu ce07cd8144 fix(cli): ignore session_db_kwargs for sqlite session services
Close issue #4317

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 864979145
2026-02-03 11:49:13 -08:00
George Weale 706a6dda81 fix: Update OpenTelemetry dependency versions
Relax version constraints for opentelemetry-api and opentelemetry-sdk to allow versions between 1.36.0 and 1.40.0

Close #4229

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 864896212
2026-02-03 08:41:39 -08:00
George Weale da73e718ef fix: Enable pool_pre_ping by default for non-SQLite database engines
This change sets `pool_pre_ping=True` in SQLAlchemy engine kwargs for database backends other than SQLite. This helps ensure that connections from the pool are still valid before being used, preventing issues with stale or disconnected connections. Tests are added to verify the default behavior and that explicit overrides are respected

Close #4211

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 864886767
2026-02-03 08:16:55 -08:00
Google Team Member 125bc85ac5 fix: Resolving MutualTLSChannelError 'OpenSSL' module error on by adding pyopenssl dependency in pyproject.toml
- Add 'pyopenssl' to project dependencies to fix MutualTLSChannelError  encountered during mTLS channel configuration.

PiperOrigin-RevId: 864874340
2026-02-03 07:43:09 -08:00
Google Team Member 6ff10b23be chore: Replace proxy methods with utils implementation
PiperOrigin-RevId: 864802559
2026-02-03 04:01:55 -08:00
Google Team Member f82ceb0ce7 chore: Replace proxy methods with utils implementation
PiperOrigin-RevId: 864773118
2026-02-03 02:27:46 -08:00
George Weale 33012e6dda fix: Make credential key generation stable and prevent cross-user credential leaks
This change updates the credential key generation to use a stable hash (SHA256) instead of Python's built-in hash, which can vary based on PYTHONHASHSEED. It also makes sure that temporary or exchanged OAuth2 fields are excluded from the key calculation. I also added when saving credentials, a copy of the AuthConfig is used to avoid modifying the original shared AuthConfig instance with user-specific exchanged credentials.

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 864599326
2026-02-02 17:51:19 -08:00
George Weale 666cebe369 fix: Add update_timestamp_tz property to StorageSession
This property is a compatibility alias that returns the update timestamp as a POSIX timestamp. It infers whether the database is SQLite using sqlalchemy.inspect to call get_update_timestamp correctly

Close #4334

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 864595914
2026-02-02 17:39:42 -08:00
George Weale dd8cd27b2c chore: Replace print statements with logging in ADK
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 864588921
2026-02-02 17:16:27 -08:00
Max Ind e87a8437fb feat(otel): add extra attributes to span generated with opentelemetry-instrumentation-google-genai
Co-authored-by: Max Ind <maxind@google.com>
PiperOrigin-RevId: 864272319
2026-02-02 03:17:08 -08:00
Google Team Member 7d58e0d2f3 feat: Mark Vertex calls made from non-gemini models
PiperOrigin-RevId: 864253424
2026-02-02 02:23:56 -08:00
Vasilii Novikov 9290b96626 feat: Make OpenAPI tool async
Merge https://github.com/google/adk-python/pull/2872

Closes https://github.com/google/adk-python/issues/787

The OpenAPI tool has been ported to the httpx client to make requests truly asynchronous.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2872 from condorcet:async_openapi_tool bf83f73af93f624126462fb0bd41fef27c53a0b6
PiperOrigin-RevId: 864250822
2026-02-02 02:15:52 -08:00
Xiang (Sean) Zhou 2770012cec chore: Add sample agent that need to go through oauth flow during mcp tool listing
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 864133951
2026-02-01 20:22:25 -08:00
Xiang (Sean) Zhou 131fbd3948 fix: Fix Pydantic Schema Generation Error for ClientSession
Problem: The test test_openapi_json_schema_accessible was failing because Pydantic couldn't generate a JSON schema for mcp.client.session.ClientSession, which is part of genai_types.ToolListUnion.

Root Cause: The AgentDetails model in src/google/adk/evaluation/app_details.py:37 had tool_declarations: genai_types.ToolListUnion, and ToolListUnion includes mcp.client.session.ClientSession which doesn't have Pydantic core schema support. This model is used in the FastAPI app through EvalCase → Invocation → AppDetails → AgentDetails, causing OpenAPI schema generation to fail.

Solution: Changed the type annotation from genai_types.ToolListUnion to list[Any] in two places:

AgentDetails.tool_declarations
_ToolDeclarations.tool_declarations

This allows Pydantic to generate the OpenAPI schema while maintaining runtime compatibility (the field still accepts the same values).

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 863765002
2026-01-31 16:26:30 -08:00
Xiang (Sean) Zhou 798f65df86 feat(tools): Implement toolset auth for McpToolset, OpenAPIToolset, and others
Update existing toolsets to utilize the new toolset authentication framework. Key changes:
        - McpToolset: Add _auth_config instance variable, _get_auth_headers()
          method to build auth headers from exchanged credentials, and
          get_auth_config() override. Auth headers are now included when
          creating MCP sessions.
        - OpenAPIToolset: Add _auth_config and get_auth_config() to expose
          auth configuration to the framework.
        - ApplicationIntegrationToolset: Add _auth_config and get_auth_config().
        - APIHubToolset: Add _auth_config and get_auth_config().

When ADK resolves toolset auth before calling get_tools(), it populates exchanged_auth_credential on the auth_config. Toolsets can then use this credential when making authenticated requests.

Also update test fixtures in test_apihub_toolset.py to use real auth objects instead of mocks that fail pydantic validation.

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 863764941
2026-01-31 16:25:46 -08:00
Xiang (Sean) Zhou ee873cae2e feat(auth): Add framework support for toolset authentication before get_tools
This change adds framework-level support for resolving toolset authentication before calling get_tools(). Key changes:
    - Add _resolve_toolset_auth() method in BaseLlmFlow that iterates
      through toolsets, checks for auth config, and resolves credentials
      via CredentialManager before tool listing
    - Add TOOLSET_AUTH_CREDENTIAL_ID_PREFIX constant for identifying
      toolset auth requests
    - Add skip logic in auth_preprocessor to not resume function calls
      for toolset auth (they do not need it)
    - Add get_auth_response() method to CallbackContext for retrieving
      auth credentials from session state
    - Update CredentialManager to accept CallbackContext instead of
      requiring ToolContext

When a toolset needs authentication but credentials are not available, the flow yields an adk_request_credential event and interrupts the invocation, allowing the user to complete the OAuth flow before retrying.

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 863543036
2026-01-30 22:36:13 -08:00
Xiang (Sean) Zhou fe82f3cde8 fix!: Make credential manager to accept tool_context instead of callback_context
This seems a breaking change, but actually credential manager is used internally only and also it won't work if some one call it using callback context

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 863534476
2026-01-30 21:59:43 -08:00
George Weale 798d0053c8 fix: Stream errors as simple JSON objects in ADK web server SSE
The ADK web server's /run_sse endpoint now yields a JSON object like {"error": "..."} when an exception occurs during event generation. The adk_web_server_client is updated to detect this error payload and raise a RuntimeError.

Close #4291

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 863475838
2026-01-30 18:18:31 -08:00
George Weale d0102ecea3 fix: Recognize function responses as non-empty parts in LiteLLM
The `_part_has_payload` helper now returns False for parts containing a function response, preventing the addition of fallback user content when a user turn consists solely of tool outputs.

Close #4249

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 863319497
2026-01-30 11:20:50 -08:00
Liang Wu 63a8eba53f fix: Ensure database sessions are always rolled back on errors
Fixes issue#3328

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 863314939
2026-01-30 11:10:02 -08:00
George Weale 47221cd5c1 fix: Handle HTTP/HTTPS URLs for media files in LiteLLM content conversion
For providers that typically require file IDs (like OpenAI and Azure), if a file URI is an HTTP/HTTPS URL and the MIME type is image, video, or audio, convert it to the corresponding URL-based content type (e.g., "image_url") instead of using the generic "file" type

Close #4112

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 863311703
2026-01-30 11:02:29 -08:00
George Weale 2ac468ea7e fix: Add pre-deployment validation for agent module imports
This change introduces a new function, _validate_agent_import, which attempts to import the user's agent.py file before the deployment process begins. This helps catch common issues such as missing dependencies, incorrect relative imports, or syntax errors in the agent code early, providing more informative error messages to the user.

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 863310033
2026-01-30 10:58:15 -08:00
Google Team Member 00aba2d884 feat: Improve asyncio loop handling and test cleanup
This CL enhances asyncio event loop management and test isolation.

-   **BigQuery Analytics Plugin:** Ensure the asyncio event loop is consistently closed within the BigQuery analytics plugin. This prevents potential resource leaks. Add checks to handle potential deadlocks in Python 3.13+ when creating loops during interpreter shutdown.
-   **Test Thread Pool Cleanup:** Introduce a pytest fixture (`cleanup_thread_pools`) to automatically shut down and clear all tool-related thread pools after each test run in `test_functions_thread_pool.py`. This improves test isolation and prevents order-dependent test failures.
-   **Streaming Test Loop Restoration:** Refactor event loop handling in `test_streaming.py`. A new `_run_with_loop` method is introduced in the custom test runners to create a temporary event loop for each test execution, run the coroutine, and crucially, restore the original event loop afterwards. This prevents tests from interfering with each other's loop state.
-   **Resource Closure:** Ensure services are closed properly in tests by adding `await service.close()` in `test_service_factory.py` and using `async with session_service` in `test_session_service.py`.

PiperOrigin-RevId: 863305565
2026-01-30 10:47:09 -08:00
Xuan Yang 585ebfdac7 feat: Support dynamic config for VertexAiSearchTool
Close: https://github.com/google/adk-python/issues/4067

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 862965769
2026-01-29 17:09:49 -08:00
Google Team Member c0c98d94b3 test: Ensure BigQueryAgentAnalyticsPlugin is shut down after each test
Improves test reliability by guaranteeing the BigQueryAgentAnalyticsPlugin is shut down after each test execution. This is achieved by wrapping test logic in try/finally blocks, using a yield fixture, or employing a new asynccontextmanager to ensure the plugin.shutdown() method is always called, preventing potential resource leaks between tests.

PiperOrigin-RevId: 862951816
2026-01-29 16:31:04 -08:00
Xuan Yang 288c2c448d chore: Add ADK logger in RestApiTool
Fixes: https://github.com/google/adk-python/issues/3780

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 862897383
2026-01-29 14:17:52 -08:00
Kathy Wu ecce7e54a6 fix: Change MCP read_resource to return the original contents
Since we will save MCP resource contents to the artifact service, no need to do post-processing based on mime type. Also fixed the implementation; the correct method to call is session.read_resource(uri).

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 862885513
2026-01-29 13:51:45 -08:00
Xiang (Sean) Zhou 381d44cab4 feat: Add get_auth_config method to toolset to expose auth requirement of the toolset
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 862597425
2026-01-29 00:23:24 -08:00
Kathy Wu 4341839420 chore: Convert MCPToolset to McpToolset in unittests
MCPToolset has been deprecated, use McpToolset instead.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 862457868
2026-01-28 17:04:14 -08:00
Sara Robinson 32f9f92042 chore: Add GitHub Action check to run mypy
Merge https://github.com/google/adk-python/pull/4276

This adds 2 mypy GitHub Actions checks:

* `mypy.yml` runs mypy on every PR. This will list all errors, so it shouldn't block until errors are resolved.
* `mypy-new-errors.yml` compares the PR branch to `main` to ensure no new mypy errors are introduced. This check can be made blocking now and can be removed once all errors are resolved in favor of `mypy.yml`.

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4276 from sararob:mypy-gh-actions 63130773c4862e90e352d4cb79221d78a6b9f5fd
PiperOrigin-RevId: 862226296
2026-01-28 07:27:52 -08:00
Google Team Member a16e3cc67e fix: Fix cases where execution_result_delimiters have None type element due to code_execution_result.output is None
PiperOrigin-RevId: 861933883
2026-01-27 16:29:51 -08:00
Kathy Wu 8f7d9659cf feat: Add methods in MCPToolset for users to access MCP resources (read_resource, list_resources, get_resource_info)
This allows users to access MCP resources on their own within agent logic / using custom tools. I plan on also later adding it to the agent state.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 861910520
2026-01-27 15:26:59 -08:00
Google Team Member 3480b3b82d feat: improve error message when failing to get tools from MCP
Include the underlying exception message in the ConnectionError raised when session.list_tools() fails.

PiperOrigin-RevId: 861889733
2026-01-27 14:33:47 -08:00
Liang Wu 65cbf4b35c fix: Make OpenAPI /docs path work again
* The main fix is in eval_metrics.py
* Removed some deprecated paths in the FastAPI server
* Added a unit test to catch future breakages
* Bump fastapi version to be 0.124.1 to capture the fix in https://github.com/fastapi/fastapi/pull/14482
* Removed the upper-bound restriction on fastapi version which was used to temporarily fix the issue

Fixes #3173

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 861867708
2026-01-27 13:41:26 -08:00
Keyur Joshi 4ee125a038 feat: Add interface for agent optimizers
Details:
* The Sampler allows ADK agent optimizers to request evals and receive detailed eval results that can be used to guide agent optimization.
* This interface allows developers to run custom evaluations if needed for their agent. An implementation to interface with the inbuilt LocalEvalService shall be published shortly in a follow-up PR.
* The AgentOptimizer interface describes the general framework for an ADK agent optimizer that uses the Sampler interface to optimize an ADK agent.
* data_types.py contains generic types and base classes to allow intercommunication between the AgentOptimizer, Sampler, and developer code.

Co-authored-by: Keyur Joshi <keyurj@google.com>
PiperOrigin-RevId: 861849691
2026-01-27 12:56:21 -08:00
Xuan Yang 2155a35c51 docs: Update ADK release analyzer to use Gemini 3 Pro with retry and improve file filtering
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 861784867
2026-01-27 10:31:03 -08:00
nikkie 3bcd8f7f7a fix: EscapieClick’s Wrapping in adk eval help (#4258)
Fix https://github.com/google/adk-python/issues/4257

https://click.palletsprojects.com/en/stable/documentation/#escaping-click-s-wrapping

Co-authored-by: Ankur <ankusharma@google.com>
2026-01-27 09:13:55 -08:00
Google Team Member c34615ecf3 fix: disable save_input_blobs_as_artifacts deprecation warning message for users that don't set it
PiperOrigin-RevId: 861738532
2026-01-27 08:38:46 -08:00
Shangjie Chen 1063fa532c fix: Reload the stale session in database_session_service when the update_time of storage is later than the current in memory session object
This changes the behavior of how we handle stale session, instead of reject the transaction entirely, we aggresively refresh the session.

Removed synchronous inspect(self).session calls within StorageSession.update_timestamp_tz and _dialect_name. This introspection was causing deadlocks/hangs when used with sqlalchemy.ext.asyncio in Python 3.13.

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

Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 861353058
2026-01-26 14:19:14 -08:00
Ankur Sharma 43d6075ea7 feat: allow Vertex AI Client initialization with API Key
Co-authored-by: Ankur Sharma <ankusharma@google.com>
PiperOrigin-RevId: 861335865
2026-01-26 13:36:41 -08:00
Joseph Pagadora 553e376718 feat: Remove overall_eval_status calculation from _CustomMetricEvaluator and add threshold to custom metric function expected signature
Co-authored-by: Joseph Pagadora <jcpagadora@google.com>
PiperOrigin-RevId: 861268984
2026-01-26 11:01:32 -08:00
Jinhyuk Kim 85434e293f feat: Pass event id as a metadata when it is converted into a message
PiperOrigin-RevId: 860929058
2026-01-25 16:05:45 -08:00
Google Team Member 324796b4fe feat: This change restructures the bug report template as per intake process
PiperOrigin-RevId: 860304319
2026-01-23 16:43:56 -08:00
Xuan Yang 853a3b0e14 fix: Do not treat FCs and FRs as invisible when marked as thoughts
Related: https://github.com/google/adk-python/issues/4159

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 860254198
2026-01-23 14:25:42 -08:00
Xiang (Sean) Zhou 714c3ad047 feat: Support run tools in separate thread for live mode
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 860242861
2026-01-23 13:55:31 -08:00
George Weale 801233902b fix: fix agent config path handling in generated deployment script
The generated agent deployment script now uses os.path.join and os.path.dirname(__file__) to construct the path to root_agent.yaml. This prevents issues where backslashes in Windows paths could be misinterpreted as Python escape sequences within the f-string, leading to syntax error

Close #4223

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 860236820
2026-01-23 13:39:32 -08:00
Liang Wu 025b42c836 chore: Add unittests.sh script and update CONTRIBUTING.md
This change introduces a new `unittests.sh` script to simplify running unit tests. The script automatically sets up a minimal test environment, runs `pytest`, and then restores the previous development environment. The CONTRIBUTING.md has been updated to include instructions on using this new script.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 860222798
2026-01-23 13:01:06 -08:00
Xiang (Sean) Zhou 753084fd46 refactor: Extract helper function for llm request building and response processing
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 860212868
2026-01-23 12:34:04 -08:00
Google Team Member 2380afd287 feat: Refine Feature Request Issue Template
This change updates the feature request issue template to include required and recommended sections. New questions are added to gather more details on the problem, impact, willingness to contribute, and potential API/implementation ideas. Existing questions are rephrased for clarity

PiperOrigin-RevId: 860199885
2026-01-23 12:00:38 -08:00
Kathy Wu 316463be86 docs: Move mcp session feature out of breaking changes
Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 860199237
2026-01-23 11:58:54 -08:00
Xuan Yang 83c24d2e74 docs: Fix ADK release analyzer agent for large releases
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 860187312
2026-01-23 11:29:42 -08:00
Shangjie Chen e8f7aa3140 fix: Add pypika>=0.50.0 to project.toml since crewai depends on it and the default version does not work with py 3.12+
Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 860181604
2026-01-23 11:15:19 -08:00
Google Team Member 7edfb2701c docs: update data agent README to match the behavior
PiperOrigin-RevId: 860180180
2026-01-23 11:11:56 -08:00
Max Ind 0d38a3683f fix: remove print debugging artifact
Co-authored-by: Max Ind <maxind@google.com>
PiperOrigin-RevId: 860038888
2026-01-23 03:59:44 -08:00
Kathy Wu 7cf1e447d7 chore: Bumps version to v1.23.0 and updates CHANGELOG.md
Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 859790616
2026-01-22 15:03:52 -08:00
Xuan Yang 3f1b0d0957 chore: minor fix for DebugLoggingPlugin example
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 859762221
2026-01-22 14:00:17 -08:00
Max Ind 935c279f82 feat(otel): add minimal generate_content {model.name} spans and logs for non-gemini inference and when opentelemetry-inference-google-genai dependency is missing
Co-authored-by: Max Ind <maxind@google.com>
PiperOrigin-RevId: 859667045
2026-01-22 10:18:06 -08:00
Google Team Member 82fa10b71e feat: add new conversational analytics api tool set
PiperOrigin-RevId: 859449435
2026-01-21 23:31:37 -08:00
Xuan Yang bf2b56de6d fix: recursively extract input/output schema for AgentTool
Fixes: https://github.com/google/adk-python/issues/4154

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 859440231
2026-01-21 23:02:33 -08:00
Liang Wu 3d96b7883b chore: Pin litellm dependency to versions below 1.80.17
This is a stopgap before the actual fix is added for 1.80.17+.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 859351463
2026-01-21 18:43:26 -08:00
Didier Durand 91ec80c606 docs: fixing multiple typos
Merge https://github.com/google/adk-python/pull/4221

### Link to Issue or Description of Change

N/A

**2. Or, if no issue exists, describe the change:**

Fixing various typos in .py files to improve quality: see commit diffs for details

**Problem:**

See above

**Solution:**
Fixing the typos

### Testing Plan

N/A

**Unit Tests:**

N/A

**Manual End-to-End (E2E) Tests:**

N/A

### Checklist

- [X] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [X] I have performed a self-review of my own code.
- [N/A] I have commented my code, particularly in hard-to-understand areas.
- [N/A ] I have added tests that prove my fix is effective or that my feature works.
- [N/A] New and existing unit tests pass locally with my changes.
- [N/A] I have manually tested my changes end-to-end.
- [N/A ] Any dependent changes have been merged and published in downstream modules.

### Additional context

N/A

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4221 from didier-durand:fix-typos-e 1bcc8e05cdc116451222dd7fd7b0657745f769c1
PiperOrigin-RevId: 859332402
2026-01-21 17:33:51 -08:00
Shangjie Chen 295b345587 chore: Filter out adk_request_input event from content list
Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 859321034
2026-01-21 16:55:50 -08:00
lwangverizon b57a3d43e4 feat: Allow google search tool to set different model
Merge https://github.com/google/adk-python/pull/4136

**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):**

Allow google search tool to set different model #4135

**2. Or, if no issue exists, describe the change:**

_If applicable, please follow the issue templates to provide as much detail as
possible._

**Problem:**
Currently, the Google Search tool inherits and uses the same LLM model set from the parent agent for processing and summarizing search results. This creates a limitation for users who wish to decouple the agent's reasoning model from the model used for search summarization (e.g., for cost optimization or using a lightweight model for simpler summarization tasks).

**Solution:**
I have updated the Google Search tool to accept an optional LLM model parameter.
Custom Model: Users can now explicitly specify which model should be used for processing search results.
Default Behavior: If no model is specified, the tool defaults to the parent agent's model, ensuring backward compatibility.

```
    # If a custom model is specified, use it instead of the original model
    if self.model is not None:
      llm_request.model = self.model
```

### Testing Plan

Added a new test case test_process_llm_request_with_custom_model in [test_google_search_tool.py] that verifies:

When a custom model parameter is provided to GoogleSearchTool, it overrides the model from the incoming llm_request during process_llm_request
The tool correctly uses the custom model for LLM calls while maintaining other request parameters

**Unit Tests:**

- [X] I have added or updated unit tests for my change.
- [X] All unit tests pass locally.

(base) wanglu2:adk-python/ (feature/allow-google-search-tool-set-different-llm✗) $ uv run pytest ./tests/unittests/tools/test_google_search_tool.py       [22:07:32]
======================================================================== test session starts ========================================================================
platform darwin -- Python 3.13.1, pytest-9.0.2, pluggy-1.6.0
rootdir: /Users/wanglu2/Documents/Git/adk-python
configfile: pyproject.toml
plugins: mock-3.15.1, anyio-4.12.0, xdist-3.8.0, asyncio-1.3.0, langsmith-0.6.0
asyncio: mode=Mode.AUTO, debug=False, asyncio_default_fixture_loop_scope=function, asyncio_default_test_loop_scope=function
collected 21 items

tests/unittests/tools/test_google_search_tool.py .....................                                                                                        [100%]

======================================================================== 21 passed in 7.91s =========================================================================

### Checklist

- [X] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [X] I have performed a self-review of my own code.
- [X] I have commented my code, particularly in hard-to-understand areas.
- [X] I have added tests that prove my fix is effective or that my feature works.
- [X] New and existing unit tests pass locally with my changes.
- [X] I have manually tested my changes end-to-end.
- [ ] Any dependent changes have been merged and published in downstream modules.

### Additional context

Co-authored-by: Kathy Wu <wukathy@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4136 from lwangverizon:feature/allow-google-search-tool-set-different-llm 239ea9577bd7befc9a3574aca48dc8243d55192c
PiperOrigin-RevId: 859265757
2026-01-21 14:31:45 -08:00
Google Team Member 9579bea05d feat(plugins): Add flush mechanism to BigQueryAgentAnalyticsPlugin
This change introduces a `flush` method to the `BigQueryAgentAnalyticsPlugin`. This ensures that all pending log events are written to BigQuery before the agent's run completes.

Key changes:

- Added `flush()` method to `BigQueryAgentAnalyticsPlugin` to force write of pending events.

PiperOrigin-RevId: 859263853
2026-01-21 14:27:03 -08:00
Liang Wu 3e3566bd0e chore: Pin litellm dependency to versions below 1.81.0
Update the litellm version constraint in both project dependencies and dev dependencies to exclude versions 1.81.0 and higher because unit test breakages in GitHub actions introduced by it.

This is a stopgap before the actual fix is added. Close #4225

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 859239880
2026-01-21 13:31:01 -08:00
Xiang (Sean) Zhou a04828dd8a feat: Persist user input content to session in live mode
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 859207592
2026-01-21 12:11:01 -08:00
Didier Durand 5d941460b6 docs: Fix various typos
Merge https://github.com/google/adk-python/pull/4186

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4186 from didier-durand:main f8a52b58e133551bec1d98660fd552afd881a8b9
PiperOrigin-RevId: 859203551
2026-01-21 12:01:54 -08:00
Xiang (Sean) Zhou e3d542a5ba feat: Support authentication for MCP tool listing
Currently only tool calling supports MCP auth. This refactors the auth logic into a auth_utils file and uses it for tool listing as well. Fixes https://github.com/google/adk-python/issues/2168.

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 859201722
2026-01-21 11:57:34 -08:00
Xuan Yang d62f9c896c chore: Always skip executing partial function calls
Related: https://github.com/google/adk-python/issues/4159

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 859184844
2026-01-21 11:20:16 -08:00
Google Team Member 7b25b8fb1d fix(runner): Yield buffered function_call/function_response events during live streaming
Bug: In live streaming mode, when function_call and function_response events
arrive during active transcription, they are correctly buffered but never
yielded to the caller. This causes callers to miss these events even though
they are saved to the session.

Fix: Add yield buffered_event after appending buffered events to the session
when transcription ends.

Testing:
- Added unit test: test_live_streaming_buffered_function_call_yielded_during_transcription
- Test verifies buffered events are yielded by:
  1. Simulating partial transcription (triggers buffering)
  2. Sending function_call during transcription (gets buffered)
  3. Ending transcription (should yield buffered events)
  4. Asserting both function_call and function_response are in yielded events

Test results:
- With fix: PASSED
- Without fix (yield commented out): FAILED with "Buffered function_call event was not yielded"
- Example event flow after fix:
EVENT: partial=True, input_transcription="Show me the weather"
EVENT: function_call=get_weather, args={'location': 'NYC'} <- Now yielded
EVENT: function_response=get_weather, response={...} <- Now yielded
EVENT: partial=False, input_transcription="Show me the weather for today"
PiperOrigin-RevId: 859158546
2026-01-21 10:21:39 -08:00
Kathy Wu 910f65473f docs: Update to gemini-2.5-flash for api registry and mcp sample agents
Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 859151854
2026-01-21 10:06:46 -08:00
Google Team Member ab89d12834 refactor(plugins)!: use OpenTelemetry for BigQuery plugin tracing
This refactors the BigQueryAgentAnalyticsPlugin to use the standard OpenTelemetry API for trace and span ID generation and propagation, replacing the custom ContextVar implementation.

Key changes:
- Utilizes `opentelemetry.trace` for starting/ending spans.
- Correctly uses `opentelemetry.context` for context attachment and detachment.
- Span information is now derived from the OpenTelemetry context when available.
- Added a fallback mechanism to ensure span_id and parent_span_id are still populated if the OpenTelemetry SDK is not initialized.

To get standard OpenTelemetry trace information in BigQuery logs, users should install `opentelemetry-sdk` and initialize a global `TracerProvider` in their application *before* initializing ADK components.

Example minimal initialization:
```python
# Install: pip install opentelemetry-sdk
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
trace.set_tracer_provider(TracerProvider())
```

PiperOrigin-RevId: 858965562
2026-01-21 01:05:53 -08:00
Wei Sun (Jack) 645bd0ed10 docs: Switches to gemini 2.5 flash for two samples
Co-authored-by: Wei Sun (Jack) <weisun@google.com>
PiperOrigin-RevId: 858826742
2026-01-20 17:38:53 -08:00
Xiang (Sean) Zhou 1699b090ed chore: Update the comments of request confirmation preprocessor
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 858816547
2026-01-20 17:04:05 -08:00
George Weale 2367901ec5 chore: Upgrade to headers to 2026
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 858763407
2026-01-20 14:50:09 -08:00
Didier Durand a8f2ddd943 chore: fixing various typos
Merge https://github.com/google/adk-python/pull/4175

### Link to Issue or Description of Change

**1. Link to an existing issue (if applicable):**

N/A: just fixing typos discovered while reading the repo

**2. Or, if no issue exists, describe the change:**

No code change, just typo fixes: see commit diffs for all details

**Problem:**

Trying to improve overall repo quality

**Solution:**

Fixing typos as they get discovered

### Testing Plan

N/A

**Unit Tests:**

N/A

**Manual End-to-End (E2E) Tests:**

N/A

### Checklist

- [X] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [X] 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.
- [X] 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.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4175 from didier-durand:fix-typos-c 16e93ed2d9bc153fa0332ab1ae39633fcc5056e9
PiperOrigin-RevId: 858751240
2026-01-20 14:21:01 -08:00
George Weale 7955177fb2 fix: Update dependency versions in pyproject.toml
Bump authlib to >=1.6.6 and mcp to >=1.23.0.

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 858728187
2026-01-20 13:29:34 -08:00
George Weale 215c2f506e fix: Set LITELLM_MODE to PRODUCTION before importing LiteLLM
LiteLLM defaults to DEV mode, which automatically loads environment variables from a local `.env` file. This change sets LITELLM_MODE to PRODUCTION to prevent LiteLLM from implicitly loading `.env` files when used within ADK.

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 858723362
2026-01-20 13:16:38 -08:00
Lusha Wang 135f763325 feat: Remove @experimental decorator from AgentEngineSandboxCodeExecutor
Co-authored-by: Lusha Wang <lusha@google.com>
PiperOrigin-RevId: 858706929
2026-01-20 12:36:56 -08:00
George Weale 5257869d91 fix: Redact sensitive information from URIs in logs
This change introduces a helper function `_redact_uri_for_log` to sanitize URIs before logging. It removes user credentials from the netloc and redacts the values of query parameters, ensuring that sensitive information like passwords is not exposed in log outputs. The function is applied to all log statements and error messages that include service URIs for session, memory, and artifact services

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 858703465
2026-01-20 12:27:27 -08:00
Xuan Yang 53b67ce634 feat: Add --disable_features CLI option to ADK CLI
This flag can be used to override default feature enable state.

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 858659818
2026-01-20 10:45:32 -08:00
Wiktoria Walczak 21f63f66ee feat(cli): add otel_to_cloud flag to adk deploy agent_engine command
Co-authored-by: Wiktoria Walczak <wwalczak@google.com>
PiperOrigin-RevId: 858546581
2026-01-20 05:41:39 -08:00
Xuan Yang 69ad605bc4 feat: Use json schema for base_retrieval_tool, load_artifacts_tool, and load_memory_tool declaration when feature enabled
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 858435881
2026-01-19 23:36:53 -08:00
Liang Wu 4b29d15b3e fix: Handle async driver URLs in migration tool
The migration tool uses synchronous SQLAlchemy engines but users often provide async driver URLs (e.g., postgresql+asyncpg://) since that's what ADK requires at runtime.

This fix:
- Makes `to_sync_url()` public in `_schema_check_utils.py` for reuse
- Updates `migrate_from_sqlalchemy_pickle.py` to convert async URLs
- Updates `migrate_from_sqlalchemy_sqlite.py` to convert async URLs
- Adds comprehensive unit tests for `to_sync_url()` function
- Adds integration test for migration with async driver URLs

Fixes #4176

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 858359061
2026-01-19 19:39:20 -08:00
Xiang (Sean) Zhou 3dd7e3f1b9 chore: Update sample live streaming tools agent to use latest live models
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 858001541
2026-01-18 21:04:06 -08:00
Google Team Member 81eaeb5eba fix: Remove custom metadata from A2A response events
PiperOrigin-RevId: 857331378
2026-01-16 15:47:38 -08:00
ShaharKatz 7d4326c360 Handle None inferences in eval results for issue #2729 (#3805)
* fixed CR comments

* formatted via isort

---------

Co-authored-by: Ankur <ankusharma@google.com>
2026-01-16 12:35:08 -08:00
Ankur Sharma c222a45ef7 chore: Making the regex to catch cli reference strict by adding word boundary anchor
Right now the regex is over-matching and is returning true for references like these:
from ..utils._client_labels_utils import EVAL_CLIENT_LABEL

Co-authored-by: Ankur Sharma <ankusharma@google.com>
PiperOrigin-RevId: 857255767
2026-01-16 12:10:02 -08:00
Joseph Pagadora ea0934b993 feat: Update adk eval cli to consume custom metrics by adding CustomMetricEvaluator
Co-authored-by: Joseph Pagadora <jcpagadora@google.com>
PiperOrigin-RevId: 857229167
2026-01-16 11:05:52 -08:00
Peter Kaplan 5923da786e feat: Add is_computer_use field to agent information in adk-web server
PiperOrigin-RevId: 857218915
2026-01-16 10:41:47 -08:00
Google Team Member f92d4e397f fix: Make all parts of a thought event be marked as thought
PiperOrigin-RevId: 857218905
2026-01-16 10:40:58 -08:00
Google Team Member 7dc6adf4e5 feat: migrate ToolboxToolset to use toolbox-adk and align validation
### Description of Change

**Problem:**
The `ToolboxToolset` was relying on the legacy `toolbox-core` package. Users wanting to use the Toolbox features were forced to install the heavy `[extensions]` group, lacking a granular installation option. Additionally, `ToolboxToolset` had a validation check enforcing either `toolset_name` or `tool_names` to be present, preventing the default behavior of loading all tools (which `toolbox-adk` supports).

**Solution:**
* Refactored `ToolboxToolset` to delegate to `toolbox-adk`.
* Added a new `toolbox` optional dependency group in `pyproject.toml`.
  * Users can now run `pip install google-adk[toolbox]` to install only the necessary dependencies.
* Updated the `extensions` dependency group to replace `toolbox-core` with `toolbox-adk`.
  * This ensures existing users of `[extensions]` are not broken upon upgrade.
* Removed the restrictive validation check to allow default loading of all tools.
* Updated the `ImportError` message to guide users toward the new granular installation command.

### Testing Plan

**Unit Tests:**
- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

**Manual End-to-End (E2E) Tests:**
- Verified that the sample agent runs correctly with `toolbox-adk` locally.
- Verified that `ToolboxToolset` can now be instantiated without arguments to load all tools.

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.

PiperOrigin-RevId: 857171811
2026-01-16 08:27:16 -08:00
Liang Wu d0aef8a4fa docs: Update the migration guide for adding a new database session schema
Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 856882485
2026-01-15 17:13:08 -08:00
Akshat8510 e162bb8832 feat: Allow thinking_config in generate_content_config
Merge https://github.com/google/adk-python/pull/4117

**Overview**
 This PR implements the feature request in #4108 to allow `thinking_config` to be set directly within `generate_content_config`, bringing the Python SDK in line with the Go implementation.

 **Changes**
 - **llm_agent.py**: Relaxed the validation logic in `validate_generate_content_config` to remove the `ValueError` for `thinking_config`.
 - **Precedence Warning**: Added an override of `model_post_init` in `LlmAgent` to issue a `UserWarning` if both a `planner` and a manual `thinking_config` are provided.
 - **built_in_planner.py**: Updated `apply_thinking_config` to log an `INFO` message when the planner overwrites an existing configuration on the `LlmRequest`.

 **Testing**
 Verified with a reproduction script covering:
 1. Successful initialization of an agent with direct `thinking_config`.
 2. Validation of `UserWarning` during initialization when conflicting configurations are present.
 3. Confirmation of logger output when the planner performs an overwrite.

 Closes: #4108
 Tagging @invictus2010 for visibility.

Co-authored-by: Liang Wu <wuliang@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4117 from Akshat8510:feat/allow-thinking-config-4108 5deeb893799379c681d6822dc4a1e42f86d3ed01
PiperOrigin-RevId: 856821447
2026-01-15 14:32:06 -08:00
Kathy Wu 19315fe557 feat: Support authentication for MCP tool listing
Currently only tool calling supports MCP auth. This refactors the auth logic into a auth_utils file and uses it for tool listing as well. Fixes https://github.com/google/adk-python/issues/2168.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 856798589
2026-01-15 13:38:19 -08:00
Yeesian Ng 6dbe851fca chore: Add back unit tests for CLI utility to deploy to AgentEngine
Co-authored-by: Yeesian Ng <ysian@google.com>
PiperOrigin-RevId: 856749290
2026-01-15 11:43:07 -08:00
George Weale 6ad18cc2fc fix: Use json.dumps for error messages in SSE events
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 856737497
2026-01-15 11:14:02 -08:00
Yeesian Ng 83d7bb6ef0 fix: Use the correct path for config-based agents when deploying to AgentEngine
Co-authored-by: Yeesian Ng <ysian@google.com>
PiperOrigin-RevId: 856724694
2026-01-15 10:45:58 -08:00
Xiang (Sean) Zhou 19555e7dce fix: Support Generator and Async Generator tool declaration in JSON schema
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 856713741
2026-01-15 10:19:58 -08:00
Google Team Member ed2c3ebde9 fix: Prevent stopping event processing on events with None content
PiperOrigin-RevId: 856706510
2026-01-15 10:03:40 -08:00
nikkie 50c4b8d33a chore: Disable scheduled GitHub Actions workflows in forks
Merge https://github.com/google/adk-python/pull/4059

### Link to Issue or Description of Change

**1. Link to an existing issue (if applicable):**

- Closes: #3961

**Problem:**
Excessive notifications from periodic workflow runs (every 6 hours for triage, daily for stale-bot and docs upload) in forks where they are not needed.

**Solution:**
Add repository checks to prevent scheduled workflows from running in forked repositories.
The workflows will now only run in the main google/adk-python repository.

### Testing Plan

I think that unit tests and E2E are not needed because this change is for GitHub Actions (not ADK source code).

_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

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] 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.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4059 from ftnext:disable-fork-actions 991cc94674cd5cef2e3c2aacf243ba7dae7b88ad
PiperOrigin-RevId: 856691019
2026-01-15 09:25:19 -08:00
Anantha Narayanan 7db3ce9613 fix: 'NoneType' object is not iterable
Merge https://github.com/google/adk-python/pull/3988

### Link to Issue or Description of Change

**1. Link to an existing issue (if applicable):**

- Closes: https://github.com/google/adk-python/issues/3987
- Related: https://github.com/google/adk-python/issues/3596

**2. Or, if no issue exists, describe the change:**

**Problem:**
Idea about my use case
I'm building the report generation system using google-ask (1.18.0) and building multiple subagents here, I'm passing the one subagent Agent as a tool to another Parent Agent. Note: Sub-agent can do web search.
here, parent agent triggers multiple sub-agent (same agent) multiple times according to use case or complexity of the user input

Describe the bug
here, the bug sometimes sub agents doesn't provide the proper output and resulted in the
```
merged_text = '\n'.join(p.text for p in last_content.parts if p.text)
^^^^^^^^^^^^^^^^^^
TypeError: 'NoneType' object is not iterable
and it's breaking the system of Agents workflow

```

**Solution:**
Creating fallback if there is no **last_content.parts** it will return the empty parts so we won't face the NoneType issue

### Testing Plan
Created a unit test file for this issue
test_google_search_agent_tool_repro.py

**Unit Tests:**

- [X] I have added or updated unit tests for my change.
- [X] All unit tests pass locally.

_Please include a summary of passed `pytest` results._
3677 passed, 2208 warnings in 42.64s

**Manual End-to-End (E2E) Tests:**
N/A

### Checklist

- [X] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [X] I have performed a self-review of my own code.
- [X] I have commented my code, particularly in hard-to-understand areas.
- [X] I have added tests that prove my fix is effective or that my feature works.
- [X] New and existing unit tests pass locally with my changes.
- [X] I have manually tested my changes end-to-end.
- [ ] Any dependent changes have been merged and published in downstream modules.

### Additional context
N/A

Co-authored-by: Liang Wu <wuliang@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3988 from ananthanarayanan-28:none-type-issue e6ba948345adfc5ac73a5e39d11c68236f117179
PiperOrigin-RevId: 856515019
2026-01-14 23:32:53 -08:00
Xuan Yang 2ed686527a feat: Use json schema for IntegrationConnectorTool declaration when feature enabled
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 856508415
2026-01-14 23:09:44 -08:00
Xiang (Sean) Zhou ec6abf4010 fix: Use canonical tools to find streaming tools and use tool.name to register them
Original codes use tool.__name__ to register streaming tools, this is problemetic, it only works with python function passed as tools directly, if they are wrapped in FunctionTool, then FunctionTool doesn't have "__name__" property. canonical_tools wrap python function in FunctionTool uniformly thus we can use tool.name uniformly

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 856472936
2026-01-14 21:00:20 -08:00
Xiang (Sean) Zhou 7c282973ea fix: Support Generator and AsyncGenerator tool declaration
use yield type as return type

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 856459995
2026-01-14 19:56:34 -08:00
Kathy Wu d4da1bb733 fix: Initialize self._auth_config inside BaseAuthenticatedTool
So that we can access self._auth_config in McpTool for getting auth headers

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 856451693
2026-01-14 19:19:08 -08:00
Kathy Wu cce430da79 feat: start and close ClientSession in a single task in McpSessionManager
Merge https://github.com/google/adk-python/pull/4025

**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:
  - #3950
  - #3731
  - #3708

**2. Or, if no issue exists, describe the change:**

**Problem:**
- `ClientSession` of https://github.com/modelcontextprotocol/python-sdk uses AnyIO for async task management.
- AnyIO TaskGroup requires its start and close must happen in a same task.
- Since `McpSessionManager` does not create task per client, the client might be closed by different task, cause the error: `Attempted to exit cancel scope in a different task than it was entered in`.

**Solution:**

I Suggest 2 changes:

Handling the `ClientSession` in a single task
- To start and close `ClientSession` by the same task, we need to wrap the whole lifecycle of `ClientSession` to a single task.
- `SessionContext` wraps the initialization and disposal of `ClientSession` to a single task, ensures that the `ClientSession` will be handled only in a dedicated task.

Add timeout for `ClientSession`
- Since now we are using task per `ClientSession`, task should never be leaked.
- But `McpSessionManager` does not deliver timeout directly to `ClientSession` when the type is not STDIO.
  - There is only timeout for `httpx` client when MCP type is SSE or StreamableHTTP.
  - But the timeout applys only to `httpx` client, so if there is an issue in MCP client itself(e.g. https://github.com/modelcontextprotocol/python-sdk/issues/262), a tool call waits the result **FOREVER**!
- To overcome this issue, I propagated the `sse_read_timeout` to `ClientSession`.
  - `timeout` is too short for timeout for tool call, since its default value is only 5s.
  - `sse_read_timeout` is originally made for read timeout of SSE(default value of 5m or 300s), but actually most of SSE implementations from server (e.g. FastAPI, etc.) sends ping periodically(about 15s I assume), so in a normal circumstances this timeout is quite useless.
  - If the server does not send ping, the timeout is equal to tool call timeout. Therefore, it would be appropriate to use `sse_read_timeout` as tool call timeout.
  - Most of tool calls should finish within 5 minutes, and sse timeout is adjustable if not.
- If this change is not acceptable, we could make a dedicate parameter for tool call timeout(e.g. `tool_call_timeout`).

### Testing Plan
- Although this does not change the interface itself, it changes its own session management logics, some existing tests are no longer valid.
  - I made changes to those tests, especially those of which validate session states(e.g. checking whether `initialize()` called).
  - Since now session is encapsulated with `SessionContext`, we cannot validate the initialized state of the session in `TestMcpSessionManager`, should validate it at `TestSessionContext`.
- Added a simple test for reproducing the issue(`test_create_and_close_session_in_different_tasks`).
- Also made a test for the new component: `SessionContext`.

**Unit Tests:**

- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

```plaintext
=================================================================================== 3689 passed, 1 skipped, 2205 warnings in 63.39s (0:01:03) ===================================================================================
```

**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

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [ ] ~~Any dependent changes have been merged and published in downstream modules.~~ `no deps has been changed`

### Additional context
This PR is related to https://github.com/modelcontextprotocol/python-sdk/pull/1817 since it also fixes endless tool call awaiting.

Co-authored-by: Kathy Wu <wukathy@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4025 from challenger71498:feat/task-based-mcp-session-manager f7f7cd0c9c96840361c30499d08c33a189f57d86
PiperOrigin-RevId: 856438147
2026-01-14 18:10:03 -08:00
Google Team Member 1133ce219c feat: convert A2UI messages between A2A DataPart metadata and ADK events
1. Convert A2A responses containing a DataPart to ADK events. By default, this is done by serializing the DataPart to JSON and embedding it within the inline_data field of a GenAI Part, wrapped with custom tags (<a2a_datapart_json> and </a2a_datapart_json>).
2. Convert ADK events back to A2A requests. Specifically, messages stored in inline_data with the text/plain mime type and content wrapped within the custom tags (<a2a_datapart_json> and </a2a_datapart_json>) are deserialized from JSON back into an A2A DataPart

PiperOrigin-RevId: 856426615
2026-01-14 17:07:54 -08:00
Xiang (Sean) Zhou 712b5a393d fix: Only filter out audio content when sending history
audio is transcribed thus no need to be sent, but other blob(e.g. image) should still be sent.

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 856422986
2026-01-14 16:51:19 -08:00
George Weale 89bed43f5e fix: Add finish reason mapping and remove custom file URI handling in LiteLLM
Introduces a function to map LiteLLM finish reason strings to the internal types.FinishReason enum and populates the finish_reason field in LlmResponse. Removes custom logic for handling file URIs, including special casing for different providers, and updates tests accordingly

Close #4125

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 856421317
2026-01-14 16:44:44 -08:00
Kathy Wu 8264211f98 chore: Consolidate test_mcp_toolset.py into one file
There was an extra test_mcp_toolset in the tools/ directory with only one test; I moved it into the main file.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 856419611
2026-01-14 16:37:12 -08:00
Xuan Yang 8e7cc16f12 docs: Refactor ADK release analyzer with workflow agents
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 856412858
2026-01-14 16:19:02 -08:00
George Weale fdc98d5c92 fix: Convert unsupported inline artifact MIME types to text in LoadArtifactsTool
The LoadArtifactsTool now checks if an artifact's inline data MIME type is supported by Gemini. If not, it attempts to convert the artifact content into a text Part

Close #4028

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 856404510
2026-01-14 16:01:06 -08:00
Xiang (Sean) Zhou 7b035aa9fc chore: Always log api backend when connecting to live model
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 856404282
2026-01-14 16:00:15 -08:00
Google Team Member 672b57f1b7 chore: add a sample BigQuery agent using BigQuery MCP tools
PiperOrigin-RevId: 856400285
2026-01-14 15:49:23 -08:00
Kotaro Saito 38d52b2476 fix(cli): pass log_level to uvicorn in web and api_server commands (#4144)
Explicitly pass the log_level parameter to uvicorn.Config in both
adk web and adk api_server commands. This ensures that Uvicorn's
internal logging respects the configured log level.

Closes #4139
2026-01-14 09:48:32 -08:00
Xuan Yang 79fcddb39f feat: Add --enable_features CLI option to ADK CLI
This flag can be used to override default feature enable state.

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 856067979
2026-01-13 23:58:26 -08:00
Xuan Yang 8973618b0b chore: Add a DebugLoggingPlugin to record human readable debugging logs
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 856067925
2026-01-13 23:57:36 -08:00
lwangverizon 8e69a58df4 feat: Add support to automatically create a session if one does not exist
feature/auto-create-new-session

Merge https://github.com/google/adk-python/pull/4072

**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

**2. Or, if no issue exists, describe the change:**

**Problem:**

When building frontend applications with ADK, there's a limitation where frontends cannot always guarantee that `create_session` is called before initiating a conversation. This creates friction in the user experience because:

- Users may refresh the page or navigate directly to a conversation URL with a specific session_id
- Frontend state management may lose track of whether a session was already created
- Mobile apps or single-page applications have complex lifecycle management where ensuring `create_session` is called first adds unnecessary complexity
- This forces developers to implement additional logic to check session existence before every conversation

Currently, if `get_session` is called with a non-existent session_id, it returns `None`, requiring the frontend to explicitly handle this case and call `create_session` separately.

**Solution:**

Modified the `get_session` method in `DatabaseSessionService` to automatically create a session if it doesn't exist in the database. This "get or create" pattern is common in many frameworks and provides a more developer-friendly API.

The implementation:
1. Attempts to fetch the session from the database
2. If the session doesn't exist (returns `None`), automatically calls `create_session` with the provided parameters
3. Retrieves and returns the newly created session
4. Maintains backward compatibility - existing code continues to work without changes

This allows frontends to simply call `get_session` with a session_id and be confident that the session will be available, regardless of whether it was previously created.

**Benefits:**
- Simplifies frontend integration by removing the need to track session creation state
- Reduces API calls (no need to check existence before calling get_session)
- Follows the principle of least surprise - getting a session with an ID should work reliably
- No breaking changes to existing code that checks for `None` return values

### Testing Plan

**Unit Tests:**

- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

**pytest results:**

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4072 from lwangverizon:feature/auto-create-new-session 5475c6ae91d12332598d521302736eb1db79a8be
PiperOrigin-RevId: 856019482
2026-01-13 21:23:49 -08:00
Xiang (Sean) Zhou 1bedffe457 chore: Remove dead codes for flushing model audio when generation completes
LlmResponse so far doesn't expose generation_complete signal, removing the dead codes.

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 855835802
2026-01-13 12:28:24 -08:00
Google Team Member 277084e313 refactor(tools): Update ToolboxToolset to wrap toolbox-adk
### Description of Change

**Problem:**
The `ToolboxToolset` was implemented directly within `adk-python`, leading to code duplication and potential drift from the core `toolbox-adk` implementation.

**Solution:**
Refactored `ToolboxToolset` to act as a rigorous wrapper around the `toolbox-adk` package, which delegates all functionality to `toolbox_adk.ToolboxToolset`.

### Testing Plan

**Unit Tests:**

- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

Summary:
-   Verified initialization flows through to `toolbox-adk`.
-   Verified `auth_token_getters` are correctly propagated.
-   Verified type hints are static-analysis friendly.

**Manual End-to-End (E2E) Tests:**

Manually verified standard toolbox loading and execution with the new wrapper:
```python
from google.adk.tools import ToolboxToolset
from toolbox_adk import CredentialStrategy

# Loading with toolset_name
ts = ToolboxToolset(
    server_url='http://localhost:8080',
    toolset_name='calculator',
    credentials=CredentialStrategy.toolbox_identity()
)
tools = await ts.get_tools()
print(f'Loaded {len(tools)} tools')
```

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.

PiperOrigin-RevId: 855798474
2026-01-13 10:59:51 -08:00
Xiang (Sean) Zhou ab62b1bffd fix: Use the agent name as the author of the audio event
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 855789317
2026-01-13 10:38:53 -08:00
Xiang (Sean) Zhou f668a5de44 chore: Update comments about why we can return upon flushing audio caches
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 855788674
2026-01-13 10:37:28 -08:00
Xuan Yang a5f0d333d7 feat: Use json schema for RestApiTool declaration when feature enabled
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 855767527
2026-01-13 09:50:59 -08:00
Google Team Member fd2c0f556b chore: Upgrade the sample BQ agent model version to gemini-2.5-flash
This change should give a more intelligent out-of-the-box experience to the sample BigQuery agent users.

PiperOrigin-RevId: 855552871
2026-01-12 23:30:16 -08:00
Joseph Pagadora 6d2f33a59c feat: Update EvalConfig and EvalMetric data models to support custom metrics
Co-authored-by: Joseph Pagadora <jcpagadora@google.com>
PiperOrigin-RevId: 855517478
2026-01-12 21:37:21 -08:00
George Weale 905604faac refactor: Import migration_runner lazily within the migrate command
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 855496468
2026-01-12 20:21:57 -08:00
Xiang (Sean) Zhou a4732a8e50 chore: Updatedate the doc string of LiveRequest
activity_start, activity_end , and blob is sent via send_realtime_input, according to the docstring : https://github.com/googleapis/python-genai/blob/d98c757c7d9a88026ac0f9eb2b1b578e2e7f3bfe/google/genai/live.py#L251, they should be send separately, so makes sense they are mutally exclusive.

And we already make them exclusive in our current logic:
https://github.com/google/adk-python/blob/6c0bf85042c38c7bafe1c183f1bba8bee1ba3570/src/google/adk/flows/llm_flows/base_llm_flow.py#L264-L272, make it clear in docstring

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 855492864
2026-01-12 20:06:08 -08:00
Liang Wu 75231a30f1 fix: Handle NOT_FOUND error when fetching Vertex AI sessions
Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 855464349
2026-01-12 18:17:41 -08:00
Alexis Marasigan b725045e5a fix: fix httpx client closure during event pagination
Merge https://github.com/google/adk-python/pull/3756

move event iteration inside api_client context in get_session

Move event iteration inside the api_client context manager in VertexAiSessionService.get_session() to prevent client closure during multi-page event fetching.

**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: #3757

**2. Or, if no issue exists, describe the change:**

**Problem:**

When a session contains more than 100 events (requiring pagination), `VertexAiSessionService.get_session()` fails with:

```
RuntimeError: Cannot send a request, as the client has been closed.
```

The root cause is that the `events_iterator` is consumed **outside** the `async with self._get_api_client() as api_client:` context block. When the iterator needs to fetch page 2, 3, etc., the API client has already been closed because the `async with` block has exited.

```python
# Current buggy flow:
async with self._get_api_client() as api_client:
    get_session_response, events_iterator = await asyncio.gather(...)
# ← Client closed here

async for event in events_iterator:  # ← Fails on page 2+ (client closed)
    session.events.append(...)
```

**Solution:**

Move the session creation, user validation, and event iteration **inside** the `async with` block so the API client remains open during the entire pagination process:

```python
async with self._get_api_client() as api_client:
    get_session_response, events_iterator = await asyncio.gather(...)
    # Validation and session creation...
    async for event in events_iterator:  # ← Now works for all pages
        session.events.append(...)
# Client closed after all events are fetched
```

### Testing Plan

**Unit Tests:**

- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

```bash
pytest tests/unittests/sessions/test_vertex_ai_session_service.py -v
```

**Added regression test:** `test_get_session_pagination_keeps_client_open`
- Creates a `MockAsyncClientWithPagination` that tracks whether it's inside the `async with` context
- Raises `RuntimeError` if iteration happens outside the context (matching real httpx behavior)
- Simulates 3 pages of events (100 + 100 + 50 = 250 events)
- Verifies all 250 events are successfully retrieved

**Manual End-to-End (E2E) Tests:**

1. Deploy an ADK agent to Vertex AI Agent Engine
2. Create a session and send 100+ messages to accumulate >100 events
3. Verify `get_session()` successfully retrieves all events without error

**Before fix:**
```
RuntimeError: Cannot send a request, as the client has been closed.
```

**After fix:**
- Session with 201 events (3 pages) loads successfully
- All events are retrieved and appended to the session

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.

### Additional context

This bug affects any production deployment where users have extended conversations. Sessions accumulating >100 events (which triggers pagination) become completely unusable as the agent cannot load the session to process new messages.

The fix is minimal and maintains backward compatibility - it only changes the scope of the `async with` block without altering any logic or return values.

**Affected versions:** Tested on google-adk 1.19.0, but the bug exists in earlier versions as well.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3756 from AlexisMarasigan:fix/vertex-ai-session-service-paginatio 01fbafa6524312f24f7c9feaffb07bff0ad49b77
PiperOrigin-RevId: 855451813
2026-01-12 17:27:29 -08:00
Google Team Member a4116a6cbf feat: Enhance TraceManager async safety, enrich BigQuery plugin logging, and fix serialization
*   **Async Safety:** Improved TraceManager context variable handling to ensure correct context isolation in concurrent asynchronous operations. This was achieved by using immutable tuples for the span stack and making copies of context dictionaries before modification.
*   **Enhanced Logging:** The BigQueryAgentAnalyticsPlugin now captures richer metadata, including:
    *   Root agent name (via a new context variable).
    *   LLM model name and version.
    *   Usage metadata from LLM requests and responses.
*   **Serialization Fix:** Updated BigQueryAgentAnalyticsPlugin to prevent JSON serialization errors when logging custom objects (e.g., Dataclasses). These are now automatically converted to dictionaries or string representations to ensure successful insertion into BigQuery.

PiperOrigin-RevId: 855415320
2026-01-12 15:46:12 -08:00
Liang Wu 2592f01eb6 chore: Bumps version to v1.22.1 and updates CHANGELOG.md
Fixing two bugs found in v1.22.0.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 855343807
2026-01-12 12:43:36 -08:00
George Weale 6c0bf85042 fix: add back migration_runner in cli_tools_click
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 855327486
2026-01-12 12:03:45 -08:00
Kathy Wu 7c8bc69dd0 fix: Ensure open api tool service account exchanger uses quota project id for ADC
gcloud auth team requested that we audit ADK's codebase for places where ADC (google.auth.default) is used, and make sure that the quota project id header is being populated.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 855322964
2026-01-12 11:51:59 -08:00
George Weale 5880109ab1 fix: Set empty JSON string as placeholder for redacted content in traces
When content capture is disabled, trace attributes for tool arguments, tool responses, LLM requests, LLM responses, and agent data are now set to the string '{}' instead of an empty dictionary

Close #4094

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 855304806
2026-01-12 11:15:28 -08:00
Tim Niemueller 458d24e24e fix: Convert examples for A2A agent card
Merge https://github.com/google/adk-python/pull/3999

The AgentSkill in an A2A AgentCard expects examples to be a list of queries as strings. Therefore, agent examples, e.g., as provided by an ExampleTool, must be converted.

This change performs that extraction of just the inputs and converting them to a string to add to the AgentSkill.

### Testing Plan

**Unit Tests:**

- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

**Manual End-to-End (E2E) Tests:**

Create an agent with ExampleTool and use agent card builder to create agent card for that agent. Fails without this change, succeeds with change included.

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3999 from timn:timn/fix-a2a-examples-from-tool 34c727c3311d2ec945efa3eec652d9e28b6ae2a9
PiperOrigin-RevId: 855288587
2026-01-12 10:37:24 -08:00
Xiang (Sean) Zhou 4a34501d38 chore: Remove unnecessary assert of live request queue
this is the only place we made the assertion , all other place called the method on live request queue directly. Also we make sure in runners that live request queue is set.

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 855285070
2026-01-12 10:30:07 -08:00
George Weale 43b484ff66 fix: Handle file URI conversion for LiteLLM based on provider and model
This change updates how `file_data.file_uri` parts are converted to LiteLLM content. For providers like OpenAI and Azure, only URIs resembling OpenAI file IDs ("file-...") are passed as file objects. Other URIs are converted to a text placeholder

Close #4038

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 855277306
2026-01-12 10:10:50 -08:00
Dinesh Thumma 94d48fce32 fix: Database reserved keyword issue
The fix will use quotes to escape "key", which is column name in the metadata table. Should work for different database types.

Merge https://github.com/google/adk-python/pull/4106

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4106 from DineshThumma9:fix/mysql-reserved-keyword-issue e39d0d02f3695d6890bc3267417b5dad58f7e8ee
PiperOrigin-RevId: 854411915
2026-01-09 18:20:46 -08:00
Google Team Member 2bd984adb3 feat: Add option to send full history to stateless RemoteA2aAgents
Introduces `full_history_when_stateless` to RemoteA2aAgent. When True, stateless agents will receive all session events on each request, instead of only events since their last reply. This allows stateless agents to have access to the complete conversation history.

PiperOrigin-RevId: 854400798
2026-01-09 17:32:20 -08:00
Google Team Member 59eda98eae feat: add SpannerVectorStore for orchestrating and providing utility functions for a Spanner vector store
PiperOrigin-RevId: 854392465
2026-01-09 16:58:44 -08:00
Liang Wu 8fb2be216f chore: Add back adk migrate session CLI
It was accidentally deleted in a previous PR. Closes #4107.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 854339442
2026-01-09 14:13:17 -08:00
Xuan Yang 6b241f5ef2 feat: Use json schema for agent tool declaration when feature enabled
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 854329254
2026-01-09 13:45:46 -08:00
saroj rout 86e7664006 feat(runners): Allow app_name to override app.name when both provided
Merge https://github.com/google/adk-python/pull/3745

This change enables Agent Engine deployments to use App objects with event compaction and context caching configs while using the Agent Engine resource name for session operations, rather than App.name.

- Allow app_name parameter to override app.name when both are provided
- Still error when app and agent are both provided (prevents confusion)
- Updated tests to reflect new behavior and added test for override case
- Updateed documentation to clarify the new usage pattern

This fixes the issue where App.name (a simple identifier) conflicts with Agent Engine's requirement for resource names in session creation.

Related to issue #3715

**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: #3715
- Related: #3715

**2. Or, if no issue exists, describe the change:**

_If applicable, please follow the issue templates to provide as much detail as
possible._

**Problem:**
When deploying an agent to Agent Engine with event compaction and/or context caching enabled, users must wrap their agent in an `App` object to configure these features. However, when the `App` is passed to `AdkApp` and deployed, session creation fails because:
1. `App.name` is validated as a simple Python identifier (e.g., `"my_agent_name"`) via `validate_app_name()`
2. Agent Engine expects the app name to be either a full Reasoning Engine resource name (e.g., `"projects/123/locations/us-central1/reasoningEngines/456"`) or the reasoning engine ID
3. When an `App` object is passed to `AdkApp`, the deployment stores `App.name` (the simple identifier), but session creation later rejects it as invalid

This prevents users from deploying to Agent Engine with event compaction or context caching enabled.

**Solution:**
Allow the `app_name` parameter in `Runner.__init__()` to override `app.name` when both are provided. This enables Agent Engine (and other deployment scenarios) to:

- Pass the full `App` object to preserve event compaction and context caching configurations
- Override `app.name` with the Agent Engine resource name for session operations
- Successfully create sessions using the resource name while maintaining App-level features

The change is backward compatible: existing code that only provides `app` continues to use `app.name` as before. The override only applies when `app_name` is explicitly provided along with `app`.

### 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:**

- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

1. **Updated existing test** (`test_runner_init_raises_error_with_app_and_agent`):
   - Changed from testing `app` + `app_name` + `agent` error to testing only `app` + `agent` error
   - Verifies that `app` and `agent` cannot both be provided (prevents confusion)

2. **Added new test** (`test_runner_init_allows_app_name_override_with_app`):
   - Verifies that `app_name` can override `app.name` when both are provided
   - Confirms that `runner.app_name == "override_name"` while `runner.app` still references the original App object
   - Ensures all App configs (agent, plugins, context_cache_config, etc.) are preserved

```
pytest tests/unittests/test_runners.py::TestRunnerWithPlugins::test_runner_init_raises_error_with_app_and_agent -v
pytest tests/unittests/test_runners.py::TestRunnerWithPlugins::test_runner_init_allows_app_name_override_with_app -v
```
tests/unittests/test_runners.py::TestRunnerWithPlugins::test_runner_init_allows_app_name_override_with_app PASSED [100%]

tests/unittests/test_runners.py::TestRunnerWithPlugins::test_runner_init_raises_error_with_app_and_agent PASSED [100%]

**Manual End-to-End (E2E) Tests:**

1. Create an agent with event compaction and context caching:
```python
from google.adk import Agent
from google.adk.apps import App
from google.adk.apps import EventsCompactionConfig
from google.adk.agents import ContextCacheConfig

root_agent = Agent(
    name="my_agent",
    model="gemini-2.5-flash",
    instruction="You are a helpful assistant.",
)

app = App(
    name="my_agent",
    root_agent=root_agent,
    events_compaction_config=EventsCompactionConfig(
        compaction_interval=2,
        overlap_size=1,
    ),
    context_cache_config=ContextCacheConfig(),
)
```

2. Create a Runner with app and override app_name:
```python
from google.adk import Runner
from google.adk.sessions import InMemorySessionService
from google.adk.artifacts import InMemoryArtifactService

runner = Runner(
    app=app,
    app_name="projects/123/locations/us-central1/reasoningEngines/456",  # Resource name
    session_service=InMemorySessionService(),
    artifact_service=InMemoryArtifactService(),
)

# Verify app_name override worked
assert runner.app_name == "projects/123/locations/us-central1/reasoningEngines/456"
assert runner.app == app  # Original app object preserved
assert runner.context_cache_config is not None  # Config preserved
assert runner.app.events_compaction_config is not None  # Config preserved
```

3. Verify session creation uses the overridden name:
```python
session = await runner.session_service.create_session(
    app_name=runner.app_name,  # Uses resource name, not app.name
    user_id="test_user",
)
```

**Expected Results:**
- Runner creation succeeds with both `app` and `app_name` provided
- `runner.app_name` equals the provided `app_name` (not `app.name`)
- All App configurations (event compaction, context caching) are preserved
- Session creation uses the overridden `app_name`

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.

### Additional context

**Backward Compatibility:**
This change is fully backward compatible. All existing code patterns continue to work:

- `Runner(app=my_app)` → Still uses `app.name`
- `Runner(app_name="x", agent=my_agent)` → Still works
- `Runner(app=my_app, app_name=None)` → Still works (uses `app.name`)

**Impact on Agent Engine:**
This change enables Agent Engine deployments to support event compaction and context caching. Once this PR is merged, Agent Engine SDK should:

1. Accept `App` objects from `AdkApp(app=my_app, ...)`
2. Create `Runner` with both `app` and `app_name` (resource name):
   ```python
   runner = Runner(
       app=my_app,  # Preserves event_compaction_config and context_cache_config
       app_name=resource_name,  # Overrides app.name for session operations
       session_service=session_service,
       ...
   )
   ```
3. Event compaction and context caching will work automatically once the App is passed correctly.

**Related Documentation:**
- Event compaction is documented in `src/google/adk/apps/compaction.py`
- Context caching is documented in `src/google/adk/agents/context_cache_config.py`
- The Runner's App support is documented in `src/google/adk/runners.py`

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3745 from sarojrout:feat/agent-engine-app-name-override 22d91d59df1460d25d06a71e155ad3dc20a69ca8
PiperOrigin-RevId: 854325898
2026-01-09 13:35:11 -08:00
Xuan Yang 0fe3870cd5 chore: Migrate the rest of tools to use the new feature decorator
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 854295648
2026-01-09 12:14:16 -08:00
George Weale fdc286a23c fix: Handle mixed tool and non-tool parts in LiteLLM content conversion
When converting a `types.Content` to LiteLLM messages, if the content contains both `function_response` parts and other types of parts (e.g., text, image), the function now generates a list of LiteLLM messages

Close #4091

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 854240746
2026-01-09 10:15:13 -08:00
Wiktoria Walczak 62fa4e513c feat(cli): add otel_to_cloud flag to adk deploy cloud_run and adk deploy gke command
Co-authored-by: Wiktoria Walczak <wwalczak@google.com>
PiperOrigin-RevId: 854087382
2026-01-09 01:43:22 -08:00
Xiang (Sean) Zhou 4dd5434847 chore: Make live request queue required
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 854058723
2026-01-09 00:05:14 -08:00
Xiang (Sean) Zhou d6c964e05e fix: Create a new session resumption config if it's None
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 853933839
2026-01-08 16:49:52 -08:00
Kathy Wu 23d330eef1 feat: Include model ID with token usage for live events
This allows users to track token usage data per model and fixes https://github.com/google/adk-python/issues/4084.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 853925212
2026-01-08 16:22:56 -08:00
George Weale b8917bc80e fix: Handle SQLite URLs in SqliteSessionService
The SqliteSessionService now accepts database paths in the form of SQLite URLs (e.g., "sqlite:///./sessions.db", "sqlite+aiosqlite:////absolute.db")

Close #4077

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 853922433
2026-01-08 16:14:07 -08:00
Sasha Sobran 3c51ee7f48 fix: fix SSRF vulnerability in load_web_page by disabling automatic redirects
Co-authored-by: Sasha Sobran <asobran@google.com>
PiperOrigin-RevId: 853901476
2026-01-08 15:13:27 -08:00
Kathy Wu f1ccc0cfca feat: Support page token in API Registry
API registry uses a nextPageToken for pagination, so we should loop through all the pages by sending the received nextPageToken to subsequent requests until no token is returned. The first page contains 1P MCP servers, and later pages contain 3P customer servers.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 853880449
2026-01-08 14:15:02 -08:00
Xiang (Sean) Zhou 8e41f7f6c8 chore: Annotate the type of transcription parameter in _has_non_empty_transcription_text
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 853880336
2026-01-08 14:14:05 -08:00
Joseph Pagadora da2c933b53 feat: Filter invocation and eval case rubrics by type when running rubric based evaluators
Co-authored-by: Joseph Pagadora <jcpagadora@google.com>
PiperOrigin-RevId: 853841204
2026-01-08 12:23:33 -08:00
Kathy Wu 226e873b0f fix: Ensure consistent ADC quota project override in ADK
Fix discovery engine search tool, bigquery agent analytics plugin, and application integration tool to correctly handle the ADC quota project override -- the x-goog-user-project should be set based on the ADC quota project, per gcloud auth team's requirements.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 853841124
2026-01-08 12:22:45 -08:00
Joseph Pagadora 8afb99a078 feat: Support per-eval case and per-invocation rubrics in rubric-based evaluators
Co-authored-by: Joseph Pagadora <jcpagadora@google.com>
PiperOrigin-RevId: 853820099
2026-01-08 11:26:06 -08:00
Liang Wu 688791396a chore: Bumps version to v1.22.0 and updates CHANGELOG.md
Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 853816883
2026-01-08 11:18:10 -08:00
George Weale 6c67b6c0f4 fix: map LiteLLM thought parts to reasoning_content
- Treat Part(thought=True) as reasoning_content when building assistant messages.
- Add unit tests for thought-only and thought+text cases.

Close #4069

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 853790274
2026-01-08 10:10:13 -08:00
Xiang (Sean) Zhou 9b2bd411dd chore: Put user_id in the error message when session is not found
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 853771033
2026-01-08 09:19:31 -08:00
Xiang (Sean) Zhou 392dda1e0c chore: Update live multi agent sample with latest live models
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 853769664
2026-01-08 09:14:45 -08:00
Google Team Member a0b2aac108 fix: Add google-cloud-geminidataanalytics to dependencies
PiperOrigin-RevId: 853515315
2026-01-07 19:57:53 -08:00
Google Team Member 3cd3d56176 fix: Add google-cloud-geminidataanalytics to dependencies
PiperOrigin-RevId: 853504915
2026-01-07 19:19:24 -08:00
Google Team Member c34feb4c0e feat: add new conversational analytics api tool set
PiperOrigin-RevId: 853489874
2026-01-07 18:26:05 -08:00
Google Team Member aaf76a6a51 feat: add new conversational analytics api tool set
PiperOrigin-RevId: 853434500
2026-01-07 15:23:43 -08:00
Yifan Wang 45a25d780b chore: update adk web to match main branch
Co-authored-by: Yifan Wang <wanyif@google.com>
PiperOrigin-RevId: 853331843
2026-01-07 10:58:37 -08:00
George Weale 5912835c97 fix: Add checks for event content and parts before accessing
Close #3769

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 853327479
2026-01-07 10:48:14 -08:00
George Weale b30c2f4e13 fix: avoid local .adk storage in Cloud Run/GKE
Default session and artifact services to in-memory when running in Cloud Run/Kubernetes (or when agents_dir isn’t writable) to prevent startup failures from attempting to create .adk under read-only/unwritable container paths (e.g. /app/agents/.adk). Local development defaults are unchanged.

  - ADK_FORCE_LOCAL_STORAGE=1 to always use .adk defaults
  - ADK_DISABLE_LOCAL_STORAGE=1 to always avoid local storage

If local artifact initialization raises PermissionError, fall back to in-memory and log a warning

Close #3907

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 853315459
2026-01-07 10:18:11 -08:00
Xiang (Sean) Zhou d5bd8d939e chore: Clean up the invocation context initialization logic for LIVE
1. Removed dead code: The if not run_config.response_modalities: branch was never executed since run_live already sets the default (https://github.com/google/adk-python/blob/19de45b3250d09b9ec16c45788e7d472b3e588c2/src/google/adk/runners.py#L947-L948).
2. Simplified condition: Changed from checking 'TEXT' not in ... to 'AUDIO' in ...

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 853274401
2026-01-07 08:31:01 -08:00
Sasha Sobran 96c5db5a07 fix: use mode='json' in model_dump to serialize bytes correctly when using telemetry
fixes #4043

Co-authored-by: Sasha Sobran <asobran@google.com>
PiperOrigin-RevId: 853256045
2026-01-07 07:38:18 -08:00
Xuan Yang 10bdc078a4 chore: Add docstring for StreamingMode
Related: #3705

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 853116282
2026-01-07 00:15:12 -08:00
Xiang (Sean) Zhou a4b914b09f fix: Set the default response modality to AUDIO only
Currently Live API only allow one response modality although the config is defined as a list.

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 853107710
2026-01-06 23:47:08 -08:00
Xiang (Sean) Zhou 19de45b325 fix: Honor the modalities parameter in adk api server for live API
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 853077949
2026-01-06 22:06:57 -08:00
George Weale b28721508a feat: make LlmAgent.model optional with a default fallback
LlmAgent now resolves model from ancestors or a system default (gemini-2.5-flash) when unset. Added LlmAgent.set_default_model() to override the default globally

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 853006116
2026-01-06 17:56:14 -08:00
George Weale 742c9265a2 fix: Validate app name in adk create command
The `adk create` command now checks if the provided agent name is a valid Python identifier. An invalid name, such as one containing hyphens, will raise a `click.BadParameter` error before any files are created.

Close #3977

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 853001295
2026-01-06 17:37:36 -08:00
Xiang (Sean) Zhou 9403a44f34 chore: Cleanup the workaround logic for streamlit
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 852995899
2026-01-06 17:18:49 -08:00
Liang Wu 35308d3809 chore: add min version of Google Auth to include fix
Context: https://github.com/googleapis/python-genai/commit/930c7ca7d5b696d3388fe16fb724184eb88c6a65. The GenAI SDK relies on Google Auth for the fix, and adding this as a direct dependency in ADK will decouple the release of ADK and GenAI SDK.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 852990837
2026-01-06 17:01:16 -08:00
Xiang (Sean) Zhou ecc9f182e3 chore: remove unecessary event loop creation in LiveRequstQueue constructor
Before Python 3.10, asyncio.Queue() required a running event loop at creation time. This was deprecated in 3.8-3.9 and fully removed in 3.10. ADK requires Python 3.10+, thus remove this unecessary logic

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 852989791
2026-01-06 16:57:23 -08:00
George Weale 6dce7f8a8f fix: Add schema type sanitization to OpenAPI spec parser
This change introduces a `_sanitize_schema_types` method to the OpenAPI spec parser. This method recursively removes or filters out non-standard schema types (e.g., "Any", "Unknown") from the OpenAPI specification

Close #3704
Close #3108

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 852986491
2026-01-06 16:47:06 -08:00
Liang Wu ce64787c3e feat: Add database schema migration command and script
Final part of https://github.com/google/adk-python/discussions/3605.

This change introduces:
-   A new `adk migrate session` CLI command to run database schema upgrades.
-   A migration script to upgrade from the old Pickle-based session schema (v0) to the new JSON-based schema (v1).
-   A migration runner that orchestrates the upgrade process, handling sequential migrations and using temporary SQLite databases for intermediate steps if needed.
-   Unit tests for the v0 to v1 migration.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 852983323
2026-01-06 16:36:45 -08:00
George Weale 0827d12ccd fix: Prevent .env files from overriding existing environment variables
This change modifies `load_dotenv_for_agent` to first capture the environment variables already set in the process. After loading the `.env` file with `override=True`, it restores the values of these initially set variables, ensuring that explicitly set environment variables are not overwritten by the `.env` file. A new environment variable, `ADK_DISABLE_LOAD_DOTENV`, is also introduced to completely skip the `.env` loading process

Close #4020
Close $4018

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 852981654
2026-01-06 16:31:24 -08:00
Liang Wu 8329fec0fc chore: Add disambiguation message to enterprise_search_tool
Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 852969034
2026-01-06 15:56:22 -08:00
George Weale 1ace8fc678 fix: Filter out thought parts in lite_llm._get_content
Thought parts represent internal model reasoning and should not be included in the content sent back to the model in subsequent turns

Close #3948

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 852965417
2026-01-06 15:44:33 -08:00
George Weale 084fcfaba5 fix: Split SSE events with both content and artifactDelta in ADK Web Server
This change modifies the /run_sse endpoint to split events that contain both content and an artifactDelta. The original event is split into two separate SSE events: one containing only the content (with artifactDelta cleared) and another containing only the artifactDelta (with content cleared)

Close #4036

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 852945249
2026-01-06 14:51:37 -08:00
George Weale 1ae0e16b2c fix: Remove fallback to cached exchanged credential in _load_existing_credential
The _load_existing_credential method in CredentialManager will now only attempt to load credentials from the credential service and will no longer check the AuthConfig's exchanged_auth_credential cache.

Close #3772

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 852944533
2026-01-06 14:50:05 -08:00
George Weale 30d3411d60 fix: Prevent retry_on_errors from retrying asyncio.CancelledError
The retry_on_errors decorator in mcp_session_manager.py now catches asyncio.CancelledError and re-raises it immediately, ensuring that cancellation requests are not suppressed or retried

Close #4009

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 852468382
2026-01-05 14:58:26 -08:00
Xiang (Sean) Zhou 6f2c70fc33 chore: add docstring for BIDI streaming mode
BIDI streaming mode is not used currently.

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 852461564
2026-01-05 14:41:09 -08:00
George Weale fc4e3d6f60 fix: Fix double JSON encoding when saving eval set results
The `model_dump_json()` method already returns a JSON string, so wrapping it in `json.dumps()` was causing double encoding

Close #3993

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 852455534
2026-01-05 14:26:05 -08:00
Michael Jones bfed19cd78 feat: expose mcps streamable http custom httpx factory parameter
Merge https://github.com/google/adk-python/pull/3634

Reopen of https://github.com/google/adk-python/pull/2997 after the accepted changes in that PR were reverted by https://github.com/google/adk-python/commit/e15e19da05ee1b763228467e83f6f73e0eced4b5

---

This PR addresses https://github.com/google/adk-python/issues/3005 and https://github.com/google/adk-python/issues/2963 to allow control over the ssl cert used when connecting to an mcp server by exposing the `httpx_client_factory` parameter exposed when creating a `MCPSessionManager` in adk. Overlaps with https://github.com/google/adk-python/pull/2966 but I don't believe that that PR's implementation will work. `streamablehttp_client` needs a client factory, not a client.

## testing plan

Adds test checking that `streamablehttp_client` uses the custom httpx factory. Could also test that a factory which obeys the `McpHttpClientFactory` protocol produces valid behavior when the session is opened?

## related issues

#2227 and #2881 both request _slightly different_ options to control the ssl certs used internally by adk. I think exposing a httpx factory is a good pattern which could be followed for those issues too.

Co-authored-by: Kathy Wu <wukathy@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3634 from mikeedjones:feat/expose-mcps-streamable-http-custom-httpx-factory-parameter 1017a9875c697b28b96a7a8d1311494ef89af65a
PiperOrigin-RevId: 852443631
2026-01-05 13:57:26 -08:00
George Weale e3db2d0d83 fix: Propagate RunConfig custom metadata to all events
Adds a method to merge custom metadata from the RunConfig into each Event. This metadata is applied to events generated by the agent, early exit events, and the initial user message event.

Close #3953

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 852433171
2026-01-05 13:30:09 -08:00
George Weale 4ddb2cb2a8 chore: Close database engines to avoid aiosqlite pytest hangs
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 852428755
2026-01-05 13:18:08 -08:00
Google Team Member 8789ad8f16 fix: Include back-ticks around the BQ asset names in the tools examples
These changes add extra hint for the LLM in the `execute_tool` SQL examples to always use back-ticks around BQ project, dataset and table names in the generated SQL, to save the SQL parsing error when the name has special characters.

PiperOrigin-RevId: 852418943
2026-01-05 12:52:49 -08:00
George Weale 93d6e4c888 fix: Allow string values for ToolTrajectoryCriterion.match_type
Adds a Pydantic field validator to ToolTrajectoryCriterion to automatically convert string inputs for the match_type field into the corresponding MatchType enum member

Close #3711

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 852415560
2026-01-05 12:43:53 -08:00
Xiang (Sean) Zhou e850e9c9ba chore: Update disconnecting log message
websocket disconnection could happen in both sending/receiving text, update the log message to make it less confusing.

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 852410439
2026-01-05 12:30:15 -08:00
George Weale 838530ebe0 fix: rehydration of EventActions in StorageEvent.to_event
The change updates the `StorageEvent.to_event` method to use `EventActions.model_validate` when rehydrating the `actions` field. This ensures that nested models within `EventActions`, such as `EventCompaction`, are correctly reconstructed from the stored data

Close #4047

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 852408683
2026-01-05 12:26:10 -08:00
Mimi Sun 8bed01cbdc fix: make the BigQuery analytics plugin work with agents that don't have instructions such as the LoopAgent
PiperOrigin-RevId: 852382657
2026-01-05 11:21:25 -08:00
George Weale e32f017979 fix: Prevent ContextFilterPlugin from creating orphaned function responses
When truncating conversation history, make sure function_response messages always have their corresponding function_call included

Close #4027

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 852377919
2026-01-05 11:09:52 -08:00
George Weale 688f48fffb fix: Update empty event check to include executable code and execution results
Close #3859
Close #3921

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 852375447
2026-01-05 11:04:34 -08:00
George Weale 6f259f08b3 fix: Harden YAML builder tmp save/cleanup
- Add path-safe helpers so all builder filesystem operations stay under <agents_dir>/<app_name> and reject traversal/invalid upload paths.
- Rework /builder/save to support tmp=true writes under <app>/tmp/<app>, promote tmp → app root on final save (preserving tools.py/tools/), then clean up tmp on success.
- Simplify /builder/app/{app_name}/cancel to best-effort delete tmp; update GET /builder/app/{app_name}?tmp=true to auto-recreate tmp from the app root and safely serve requested files.

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 852366567
2026-01-05 10:47:12 -08:00
Rohit Yanamadala 3ec7ae3b8d fix: ignore adk-bot administrative actions in stale agent
Merge https://github.com/google/adk-python/pull/4041

## Description
This PR fixes false positive stale labels in the `adk_stale_agent`.

Previously, the agent was incorrectly identifying the issue as "stale" because it treated `adk-bot` (acting via PAT) as a human maintainer. Since the username lacks the `[bot]` suffix, administrative alerts (e.g., "Notification: The author has updated...") were counted as maintainer activity, inadvertently triggering the stale logic immediately after an author's edit.

## Changes Made
- **Hardcoded Bot Exclusion:** Added `BOT_NAME = "adk-bot"` and updated history parsing loops (comments, edits, timeline) to explicitly ignore this actor.
- **Bot Alert Skip:** Added logic to `continue` (skip) processing the bot's specific "Notification" comment so it is not recorded as the last activity on the timeline.

Co-authored-by: Xuan Yang <xygoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4041 from ryanaiagent:fix/stale-bot-logic f1500a94cb8c9d5090e9b1ef29690506120f7749
PiperOrigin-RevId: 852365962
2026-01-05 10:45:58 -08:00
George Weale 6b7386b762 fix: Heal missing tool results before LiteLLM requests
Detect assistant tool calls that lack matching tool results in the history and insert placeholder tool messages so strict providers don’t reject the request. Prevents crash loops when executions are interrupted mid-tool call.

Close #3971

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 852340750
2026-01-05 09:49:20 -08:00
Joseph Pagadora 5b7c8c04d6 chore: Introduce MetricInfoProvider interface, and refactor metric evaluators to use this interface to provide MetricInfo
Co-authored-by: Joseph Pagadora <jcpagadora@google.com>
PiperOrigin-RevId: 851406110
2026-01-02 11:49:34 -08:00
Google Team Member 07bb164758 fix: Exclude thought parts when merging agent output
PiperOrigin-RevId: 850500329
2025-12-30 13:39:40 -08:00
Keyur Joshi a364388d97 feat: Add custom instructions support to LlmBackedUserSimulator
Details:
- Allows users to provide custom instructions for the LLM-backed user simulator via the `custom_instructions` field in `LlmBackedUserSimulatorConfig`.
- The custom instructions must include placeholders for the stop signal, conversation plan, and conversation history. A pydantic validator ensures these placeholders are present.
- If no custom instructions are provided, the current default template is used.

Co-authored-by: Keyur Joshi <keyurj@google.com>
PiperOrigin-RevId: 850471448
2025-12-30 11:42:46 -08:00
Keyur Joshi 0918b647df fix: fix inconsistent method signatures for evaluate_invocations
The evaluate_invocations method override in Evaluator subclasses was not consistent, leading to errors during calls, especially when using kwargs. Made the overrides and calls consistent to resolve this issue.

Co-authored-by: Keyur Joshi <keyurj@google.com>
PiperOrigin-RevId: 850462752
2025-12-30 11:07:25 -08:00
Yeesian Ng 38a30a44d2 fix: Handle overriding of requirements when deploying to agent engine
Co-authored-by: Yeesian Ng <ysian@google.com>
PiperOrigin-RevId: 850423017
2025-12-30 08:30:35 -08:00
Google Team Member 26e77e1694 fix: Fix issue with MCP tools throwing an error
Fixes: https://github.com/google/adk-python/issues/3082
PiperOrigin-RevId: 849562638
2025-12-27 15:51:03 -08:00
Yeesian Ng 1f546df35a feat: Set log level when deploying to Agent Engine
Co-authored-by: Yeesian Ng <ysian@google.com>
PiperOrigin-RevId: 848243087
2025-12-23 11:25:39 -08:00
Google Team Member 871571d997 feat: Mark Vertex calls made from non-gemini models
PiperOrigin-RevId: 848159669
2025-12-23 06:50:46 -08:00
Google Team Member 0f5b677c53 feat: Mark Vertex calls made from non-gemini models
PiperOrigin-RevId: 848140103
2025-12-23 05:37:36 -08:00
Google Team Member 4f3b733074 fix: label response as thought if task is immediately returned as working
PiperOrigin-RevId: 847660113
2025-12-22 01:21:41 -08:00
Xuan Yang 0b1cff2976 feat: Enable PROGRESSIVE_SSE_STREAMING feature by default
Related: https://github.com/google/adk-python/issues/3705

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 846793027
2025-12-19 10:50:49 -08:00
Kathy Wu 71b32890f5 fix: Only prepend "https://" to the MCP server url if it doesn't already have a scheme
There isn't a consistent format for MCP server urls in the registry-- some customers add the https:// but others don't. To standardize, only prepend if it isn't there already.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 846451152
2025-12-18 16:07:16 -08:00
Rohit Yanamadala f51b9b70b2 fix: Prevent stale bot from flagging internal maintainer discussions
Merge https://github.com/google/adk-python/pull/3938

Co-authored-by: Xuan Yang <xygoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3938 from ryanaiagent:fix/stale-bot-logic 605d3499784facffc0e0ca3c1fb0547202660f46
PiperOrigin-RevId: 846450195
2025-12-18 16:04:21 -08:00
Google Team Member e4ee9d7c46 feat: Update event_converter used in A2ARemote agent to use a2a_task.status.message only if parts are non-empty
PiperOrigin-RevId: 846413612
2025-12-18 14:23:27 -08:00
Xiang (Sean) Zhou f1eb1c0254 chore: Update latest Live Model names for sample agent
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 846351549
2025-12-18 11:33:18 -08:00
Xiang (Sean) Zhou d58ea589ad chore: Update google-genai and google-cloud-aiplatform versions
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 846307170
2025-12-18 09:42:15 -08:00
Xuan Yang f5f4c01d1b fix: Pin aiosqlite version to 0.21.0
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 846056994
2025-12-17 21:26:19 -08:00
Kathy Wu 253ac87c79 fix: nit fixes for API Registry - updating imports / type hints and formatting
Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 845980315
2025-12-17 17:23:58 -08:00
Kathy Wu 0088b0f3ad fix: Add x-goog-user-project header to http calls in API Registry
This gcloud authentication header is required as a project override when using google ADC credentials. It is required for all OneMCP servers. Originally I manually put it in the big query sample, but since it is used for all OneMCP, it makes sense to just add it to the core API Registry logic. I also refactored the auth header logic a bit to deduplicate.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 845967178
2025-12-17 16:41:50 -08:00
George Weale fcea86f58c chore: Update _flatten_ollama_content return type and add tests
The return type of _flatten_ollama_content is now strictly str | None

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 845963722
2025-12-17 16:31:43 -08:00
Google Team Member f35d129b4c feat(fix): Check all content parts for emptiness in _contains_empty_content
PiperOrigin-RevId: 845954226
2025-12-17 16:03:12 -08:00
Shangjie Chen 589f15cb27 feat: Add an internal function name 'adk_framework' to allow passing function response to the framework but not poluting the agent context
Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 845933584
2025-12-17 15:07:25 -08:00
Kathy Wu 78c96e99ff fix: update Api Registry Agent prompt to be more specific and give it the gcloud project id
Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 845884290
2025-12-17 13:00:19 -08:00
George Weale e3bac1ab8c fix: Built-in agents (names starting with "__") now use in-memory session storage instead of creating .adk folders in the agents directory
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 845852695
2025-12-17 11:36:22 -08:00
George Weale c6f389d4bc fix: Refine Ollama content flattening and provider checks
- Stripping whitespace from custom LLM provider and model names when checking for "ollama_chat".
- Enhancing `_flatten_ollama_content` to correctly handle content that is None, a string, a dictionary, or an iterable (like a tuple) of content blocks, not just lists. This aligns with LiteLLM's `OpenAIMessageContent` type being an `Iterable`.

Close #3928

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 845848017
2025-12-17 11:25:44 -08:00
Salman Chishti 1add41e160 fix: Upgrade GitHub Actions for Node 24 compatibility
Merge https://github.com/google/adk-python/pull/3932

## Summary

Upgrade GitHub Actions to their latest versions to ensure compatibility with Node 24, as Node 20 will reach end-of-life in April 2026.

## Changes

| Action | Old Version(s) | New Version | Release | Files |
|--------|---------------|-------------|---------|-------|
| `actions/checkout` | [`v5`](https://github.com/actions/checkout/releases/tag/v5) | [`v6`](https://github.com/actions/checkout/releases/tag/v6) | [Release](https://github.com/actions/checkout/releases/tag/v6) | analyze-releases-for-adk-docs-updates.yml, check-file-contents.yml, discussion_answering.yml, isort.yml, pr-triage.yml, pyink.yml, python-unit-tests.yml, stale-bot.yml, triage.yml, upload-adk-docs-to-vertex-ai-search.yml |

## Context

Per [GitHub's announcement](https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/), Node 20 is being deprecated and runners will begin using Node 24 by default starting March 4th, 2026.

### Why this matters

- **Node 20 EOL**: April 2026
- **Node 24 default**: March 4th, 2026
- **Action**: Update to latest action versions that support Node 24

### Security Note

Actions that were previously pinned to commit SHAs remain pinned to SHAs (updated to the latest release SHA) to maintain the security benefits of immutable references.

### Testing

These changes only affect CI/CD workflow configurations and should not impact application functionality. The workflows should be tested by running them on a branch before merging.

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3932 from salmanmkc:upgrade-github-actions-node24 0ffbb0b7b5f63d27583f8c24781f2d3ca92c0c23
PiperOrigin-RevId: 845813166
2025-12-17 10:01:43 -08:00
Salman Chishti fa717ad8f0 fix: Upgrade GitHub Actions to latest versions
Merge https://github.com/google/adk-python/pull/3933

## Summary

Upgrade GitHub Actions to their latest versions for improved features, bug fixes, and security updates.

## Changes

| Action | Old Version(s) | New Version | Release | Files |
|--------|---------------|-------------|---------|-------|
| `google-github-actions/auth` | [`v2`](https://github.com/google-github-actions/auth/releases/tag/v2) | [`v3`](https://github.com/google-github-actions/auth/releases/tag/v3) | [Release](https://github.com/google-github-actions/auth/releases/tag/v3) | discussion_answering.yml, upload-adk-docs-to-vertex-ai-search.yml |

## Why upgrade?

Keeping GitHub Actions up to date ensures:
- **Security**: Latest security patches and fixes
- **Features**: Access to new functionality and improvements
- **Compatibility**: Better support for current GitHub features
- **Performance**: Optimizations and efficiency improvements

### Security Note

Actions that were previously pinned to commit SHAs remain pinned to SHAs (updated to the latest release SHA) to maintain the security benefits of immutable references.

### Testing

These changes only affect CI/CD workflow configurations and should not impact application functionality. The workflows should be tested by running them on a branch before merging.

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3933 from salmanmkc:upgrade-github-actions-node24-general 142ef77d94da42b0f75a1fc810e8deeb666684a4
PiperOrigin-RevId: 845804209
2025-12-17 09:37:58 -08:00
Google Team Member 43270bcb61 fix: Move and enhance the deprecation warning for the plugins argument in "_validate_runner_params" to the beginning of the function
Previously, the warning check occurred after "plugins" could be populated from "app.plugins". This caused the deprecation warning to trigger incorrectly even when plugins were properly provided via the app argument. Moving the check ensures it only triggers when the deprecated plugins argument is explicitly used.

The change also enhanced the condition that would trigger the warning to cover the empty list case.

PiperOrigin-RevId: 845746847
2025-12-17 06:48:44 -08:00
Goodnight 322dd1827a docs: Fix typos, broken links, and grammar across documentation
Merge https://github.com/google/adk-python/pull/3937

**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
Not applicable

**Problem:**
Several markdown files contained typos, grammatical errors (e.g., "search youtubes"), and awkward phrasing.
**Solution:**
Performed a comprehensive quality assurance pass on the documentation.
- Fixed typos in README.md and AGENTS.md.
- Improved grammar and phrasing in CONTRIBUTING.md and sample READMEs.

### Testing Plan

This is a documentation and typo fix PR.

**Unit Tests:**

- [ ] I have added or updated unit tests for my change.
- [ ] All unit tests pass locally.
N/A - Documentation changes only.

**Manual End-to-End (E2E) Tests:**

This is a documentation and typo fix PR.

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] 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.
- [x] I have manually tested my changes end-to-end.
- [ ] Any dependent changes have been merged and published in downstream modules.

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3937 from Goodnight77:docs/fix-typos a0cf4db6741f19c77eeb0746c9db524dd02121ac
PiperOrigin-RevId: 845599254
2025-12-16 22:45:02 -08:00
Hiroaki Sano 42317f849f fix: Add missing space in README.md
Merge https://github.com/google/adk-python/pull/3939

### Link to Issue or Description of Change

**1. Link to an existing issue (if applicable):**

n/a

**2. Or, if no issue exists, describe the change:**

**Problem:**
In the Community Repo section of README.md, there was a missing space between the markdown link `[adk-python-community repo](...)` and the word `that`, causing the text to render as `repo](...)that` instead of `repo](...) that`.

**Solution:**
Add a single space between the closing parenthesis of the markdown link and the word "that" to fix the typo.

### Testing Plan

**Unit Tests:**

This is a small documentation/typo fix. No code changes were made.

**Manual End-to-End (E2E) Tests:**

I verified that the markdown renders correctly with proper spacing between the link and following text.

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.

### Additional context

This is a minor typo fix in the README.md file. No functional changes.

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3939 from hiroakis:fix-readme-typo f4e8014367961b55124da57b5c910890a287b2af
PiperOrigin-RevId: 845595505
2025-12-16 22:33:06 -08:00
Liang Wu ba91fea541 feat: Use new JSON-based schema for newly-created databases
Part 2 of https://github.com/google/adk-python/discussions/3605.

The DatabaseSessionService now checks for the usage of a V1 schema based on the "adk_internal_metadata" table. Table creation and subsequent operations use either the V0 or V1 SQLAlchemy models accordingly. New databases will default to V1.

Migration script and CLI command will be provided in the next change.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 845443406
2025-12-16 14:49:31 -08:00
Xiang (Sean) Zhou 2ea6e513cf feat: support regex for allowed origins
fixes https://github.com/google/adk-python/issues/3908

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 845397350
2025-12-16 12:53:35 -08:00
Kamal Aboul-Hosn b6f6dcbeb4 feat: Add a handwritten tool for Cloud Pub/Sub
Merge https://github.com/google/adk-python/pull/3865

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3865 from kamalaboulhosn:main 37a38a4dcadb04a0af0ec584e6f611204a63cd2a
PiperOrigin-RevId: 845345128
2025-12-16 10:48:09 -08:00
Liang Wu 7e6ef71eec feat: Introduce new database schema for DatabaseSessionService
Part 1 of https://github.com/google/adk-python/discussions/3605.

This change adds a new schema that uses JSON serialization to store Events data in the database. A new "adk_internal_metadata" table is also added to store information like schema version. Since we want to keep supporting existing DB, we fork from the original schema and call it "v0", while the new one is called "v1".

The change is no-op for existing users. In later change, the new schema will be used for new databases, and migration scripts will be provided for existing databases.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 844986248
2025-12-15 17:32:48 -08:00
Xuan Yang a0885064b0 chore: Add override_feature_enabled to override the default feature enable states
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 844905911
2025-12-15 13:46:17 -08:00
Liang Wu e8ab7dafa9 chore: Move SQLite migration script to migration/ folder
Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 844902789
2025-12-15 13:38:51 -08:00
Hiroaki Sano 8335f35015 fix: Change error_message column type to TEXT in DatabaseSessionService
Merge https://github.com/google/adk-python/pull/3917
To migrate from existing DB :

ALTER TABLE events ALTER COLUMN error_message TYPE TEXT;  -- PostgreSQL
ALTER TABLE events MODIFY error_message TEXT;             -- MySQL
SQLite: Doesn't enforce VARCHAR length limits anyway. No impact.
### Link to Issue or Description of Change

**1. Link to an existing issue (if applicable):**

n/a

**2. Or, if no issue exists, describe the change:**

**Problem:**

When storing events with error messages longer than 1024 characters using `DatabaseSessionService`, PostgreSQL raises:

```
ERROR: value too long for type character varying(1024)
```

The `error_message` column in `StorageEvent` is defined as `String(1024)`, which maps to `VARCHAR(1024)`. Error messages can exceed 1024 characters.

**Solution:**

Change the column type from `String(1024)` to `Text` to allow unlimited length error messages.

### Testing Plan

**Unit Tests:**

- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

$ pytest ./tests/unittests/sessions/ -v
======================= 75 passed, 3 warnings in 26.92s ========================

**Manual End-to-End (E2E) Tests:**

- Verified that events with long error messages (>1024 chars) can be stored in PostgreSQL
- Verified backward compatibility with existing databases

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.

### Additional context

This is a minimal change (1 line) that only affects the `error_message` column type definition.

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3917 from hiroakis:main 1474fd552cdbd7206de383e5507fd8a733aecda1
PiperOrigin-RevId: 844845692
2025-12-15 11:09:25 -08:00
Google Team Member e515e0f321 feat: Introduce a post-hoc, per-turn evaluator for user simulations
PiperOrigin-RevId: 844818512
2025-12-15 10:05:31 -08:00
Marlin Ranasinghe 69997cd5ef fix: oauth refresh not triggered on token expiry
Merge https://github.com/google/adk-python/pull/3767

Co-authored-by: Xuan Yang <xygoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3767 from MarlzRana:marlzrana/fix-oauth-refresh-not-triggered-on-token-expiry 2dae3917de6e8d3fa5317857d06305d47c0773b0
PiperOrigin-RevId: 843756363
2025-12-12 10:57:58 -08:00
George Weale 5c4bae7ff2 fix: Add MIME type inference and default for file URIs in LiteLLM
This change ensures that file URI parts passed to LiteLLM always include a "format" field. If `mime_type` is not explicitly provided in `FileData`, the system attempts to infer it from the URI's file extension. If inference fails, a default "application/octet-stream" is used. This is necessary because LiteLLM's Vertex AI backend requires the "format" field for GCS URIs.

Close #3787

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 843753810
2025-12-12 10:51:55 -08:00
David Sullivan 8782a69503 feat: add token_endpoint_auth_method support to OAuth2 credentials
Merge https://github.com/google/adk-python/pull/2870

## Summary

  Add `token_endpoint_auth_method` field to OAuth2Auth class to allow configuring OAuth2 token endpoint authentication methods. This enables users to specify how the client should authenticate with the authorization server's token
  endpoint.

  • Add `token_endpoint_auth_method` field to `OAuth2Auth` with default value `"client_secret_basic"`
  • Update `create_oauth2_session()` to pass the authentication method to `OAuth2Session`
  • Maintain backward compatibility with existing OAuth2 configurations

  ## Unit Tests
  Added unit test coverage with 3 new test methods:

  1. `test_create_oauth2_session_with_token_endpoint_auth_method()` - Tests explicit auth method setting (`client_secret_post`)
  2. `test_create_oauth2_session_with_default_token_endpoint_auth_method()` - Tests default behavior (`client_secret_basic`)
  3. `test_create_oauth2_session_oauth2_scheme_with_token_endpoint_auth_method()` - Tests with OAuth2 scheme using `client_secret_jwt`

  **Test Results:**
   16/16 OAuth2 credential utility tests passed
   240/240 auth module tests passed (no regressions)
   Tests cover both GOOGLE_AI and VERTEX variants
   Pylint score: 9.41/10

  ## Changes Made

  **src/google/adk/auth/auth_credential.py**
  - Added `token_endpoint_auth_method: Optional[str] = "client_secret_basic"` to `OAuth2Auth` class

  **src/google/adk/auth/oauth2_credential_util.py**
  - Updated `create_oauth2_session()` to pass `token_endpoint_auth_method` parameter to `OAuth2Session`

  **tests/unittests/auth/test_oauth2_credential_util.py**
  - Added 3 comprehensive test methods covering different authentication scenarios

  ## Backward Compatibility

   **Non-breaking change** - All existing OAuth2 configurations continue to work unchanged with the default `client_secret_basic` authentication method.

  ## Supported Authentication Methods

  - `client_secret_basic` (default) - Client credentials in Authorization header
  - `client_secret_post` - Client credentials in request body
  - `client_secret_jwt` - JWT with client secret
  - `private_key_jwt` - JWT with private key

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2870 from sully90:feat/oauth2-token-endpoint-auth-method 04fe8244598f96b4e3366f0fc79382628382e9c2
PiperOrigin-RevId: 843739984
2025-12-12 10:16:36 -08:00
Xiang (Sean) Zhou 29c1115959 chore: Bumps version to v1.21.0 and updates CHANGELOG.md
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 843427582
2025-12-11 16:54:08 -08:00
Liang Wu 60e314a78f fix: Update SQLite database URL for async connection
The example is broken without the fix.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 843424168
2025-12-11 16:42:10 -08:00
George Weale ee9b4ca908 feat: Add .yml to watched file extensions and add unit tests for AgentChangeEventHandler
Close #3834

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 843409166
2025-12-11 16:00:17 -08:00
George Weale db711cd789 fix: Redirect LiteLLM logs from stderr to stdout
LiteLLM's StreamHandlers output to stderr by default. In cloud environments like GCP, stderr output is treated as ERROR severity regardless of actual log level, causing INFO-level logs to be incorrectly classified as errors.

This change redirects LiteLLM loggers to stdout in two places:
- In `lite_llm.py`: Immediately after litellm import
- In `logs.py`: When `setup_adk_logger()` is called (with guard to check if litellm is imported)

Close #3824

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 843393874
2025-12-11 15:14:15 -08:00
George Weale 055dfc7974 fix: Normalize multipart content for LiteLLM's ollama_chat provider
LiteLLM's `ollama_chat` provider does not accept array-based content in messages. This change flattens multipart content by joining text parts or JSON-serializing non-text parts before sending the request to the LiteLLM completion API. This ensures compatibility with Ollama's chat endpoint.

Close #3727

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 843382361
2025-12-11 14:46:37 -08:00
Yifan Wang df8684734b chore: update adk web, fixes image not rendering, state not updating, update drop down box width and trace icons
Co-authored-by: Yifan Wang <wanyif@google.com>
PiperOrigin-RevId: 843378628
2025-12-11 14:36:40 -08:00
Google Team Member 9cccab4537 fix: installing dependencies for py 3.10
PiperOrigin-RevId: 843378433
2025-12-11 14:35:51 -08:00
Xuan Yang e1a7593ae8 feat: Add header_provider to OpenAPIToolset and RestApiTool
Fixes: https://github.com/google/adk-python/issues/3782

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 843352147
2025-12-11 13:29:00 -08:00
Xuan Yang cb3244bb58 feat: Use json schema for function tool declaration when feature enabled
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 843350330
2025-12-11 13:24:41 -08:00
George Weale 894d8c6c26 fix: Refactor LiteLLM response schema formatting for different models
The `_to_litellm_response_format` function now adapts the output format based on the provided model. Gemini models continue to use the "response_schema" key, while OpenAI-compatible models (including Azure OpenAI and Anthropic) now use the "json_schema" key as per LiteLLM's documentation for JSON mode. The schema name is also included in the "json_schema" format.

Close #3713
Close #3890

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 843326850
2025-12-11 12:20:11 -08:00
George Weale 99f893ae28 fix: Resolve project and credentials before creating Spanner client
Explicitly resolve the GCP project from arguments or environment variables before calling `spanner.Client`. This avoids redundant calls to `google.auth.default()` that newer versions of the Spanner library might make.

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 843320305
2025-12-11 12:03:10 -08:00
Google Team Member 7b2fe14dab feat: Upgrade BigQueryAgentAnalyticsPlugin to v2.0
Performance: Switched to BigQuery Storage Write API with async batching, reducing agent latency.
Multimodal: Native support for GCS offloading (ObjectRef) for images, video, and large text.
Reliability: Added connection pooling, retries, and a "rescue flush" for safe shutdown on Cloud Run.
Observability: Fixed distributed tracing hierarchy with ContextVars support.
PiperOrigin-RevId: 843062561
2025-12-10 23:04:01 -08:00
Xiang (Sean) Zhou 68d70488b9 chore: Add sample agent for interaction api integration
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 843037705
2025-12-10 21:37:03 -08:00
Xiang (Sean) Zhou c6320caaa5 feat: Support interactions API for calling models
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 843032402
2025-12-10 21:21:14 -08:00
Xiang (Sean) Zhou f0bdcaba44 chore: Update genAI SDK version
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 843030125
2025-12-10 21:13:52 -08:00
George Weale 7b356ddc1b feat: Add add_session_to_memory to CallbackContext and ToolContext
This change introduces an add_session_to_memory method to both CallbackContext and ToolContext, allowing agents and tools to explicitly trigger the saving of the current session to the memory service. This enables more fine-grained control over when session data is persisted for memory generation. A ValueError is raised if the memory service is not configured.

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 843021899
2025-12-10 20:47:08 -08:00
Krishna vamsi Dhulipalla 4111f85b61 docs(adk): fix run_async example and correct ticketId payload key
Merge https://github.com/google/adk-python/pull/3875

# Problem
The example in `contributing/samples/human_in_loop/README.md` shows:

```python
await runner.run_async(...)
```

However, `run_async` returns an **async generator**, so awaiting it raises:

```
TypeError: object async_generator can't be used in 'await' expression
```

Additionally, the example payload uses `"ticket-id"` while ADK tools and other examples use `"ticketId"`, creating a mismatch that breaks copy/paste usage.

# Solution
- Updated the snippet to consume the async generator correctly:

```python
async for event in runner.run_async(...):
    ...
```

- Aligned the payload key from `"ticket-id"` → `"ticketId"` for consistency with ADK schema and other examples.

These changes make the example runnable and consistent with the API’s actual behavior.

# Testing Plan
This PR is a **small documentation correction**, so no unit tests are required per contribution guidelines.

- Verified the corrected snippet manually to ensure it no longer raises `TypeError`.

# Checklist
- [x] I have read the CONTRIBUTING.md document.
- [x] I have performed a self-review of my own code.
- [ ] I have commented my code, particularly in hard-to-understand areas. *(N/A – docs only)*
- [ ] I have added tests that prove my fix is effective or that my feature works. *(N/A – docs only)*
- [ ] New and existing unit tests pass locally with my changes. *(N/A – docs only)*
- [x] I have manually tested my changes end-to-end.
- [ ] Any dependent changes have been merged and published in downstream modules. *(N/A)*

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3875 from krishna-dhulipalla:docs/fix-adk-run_async-example 83fc5b430690b63b8b7bf1025ef03b0761264751
PiperOrigin-RevId: 842952362
2025-12-10 17:24:58 -08:00
Xuan Yang b23deeb9ab docs: Update adk docs update workflow to invoke the updater agent once per suggestion
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 842789476
2025-12-10 10:45:05 -08:00
Xuan Yang 51a638b6b8 chore: Introduce build_function_declaration_with_json_schema to use pydantic to generate json schema for FunctionTool
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 842783745
2025-12-10 10:31:09 -08:00
George Weale 6388ba3b20 fix: Avoid false positive "App name mismatch" warnings in Runner
When users instantiate LlmAgent directly (not subclassed), the origin inference incorrectly detected ADK's internal google/adk/agents/ path as a mismatch.

Use metadata from AgentLoader when available
Skip inference for google.adk.* module

Close #3143

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 842774292
2025-12-10 10:08:37 -08:00
Google Team Member 4f54660d6d fix: Update the code to work with either 1 event or more than 1 events
Update the code to work with either 1 event or more than 1 events.

PiperOrigin-RevId: 842406345
2025-12-09 14:48:25 -08:00
Xiang (Sean) Zhou ee743bd19a chore: Update component definition for triaging agent
Context: many issues related to local mult-agent system is tagged with a2a

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 842397159
2025-12-09 14:25:18 -08:00
Xuan Yang bab57296d5 chore: Migrate Google tools to use the new feature decorator
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 842321126
2025-12-09 11:21:06 -08:00
Xuan Yang 1ae944b39d chore: Migrate computer to use the new feature decorator
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 842287104
2025-12-09 10:03:43 -08:00
hoonji 32e87f6381 feat: Adds ADK EventActions to A2A response
Merge https://github.com/google/adk-python/pull/3631

### Link to Issue or Description of Change

**1. Link to an existing issue (if applicable):**

- Closes: #3630

**Solution:**
Adds [Event.actions](https://github.com/google/adk-python/blob/a3aa07722a7de3e08807e86fd10f28938f0b267d/src/google/adk/events/event.py#L51) to A2A event metadata during ADK -> A2A event conversion (to allow A2A event consumers to access important info like state_delta, artifact delta, etc)

### Testing Plan

`pytest ./tests/unittests` passes

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3631 from hoonji:main 31d3a49ad630bbd778aa4cf62dd9ccfc50f5b7af
PiperOrigin-RevId: 842274939
2025-12-09 09:32:36 -08:00
George Weale 56775afc48 fix: OpenAPI schema generation by skipping JSON schema for judge_model_config
Close #3750

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 841991676
2025-12-08 18:20:41 -08:00
Google Team Member cde7f7c243 feat: Allow overriding connection template
PiperOrigin-RevId: 841984336
2025-12-08 17:54:25 -08:00
Xuan Yang 82e6623fa9 fix: Add tool_name_prefix support to OpenAPIToolset
Fixes: https://github.com/google/adk-python/issues/3779

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 841850614
2025-12-08 11:35:08 -08:00
Google Team Member 143ad44f8c fix: pass context to client inceptors
PiperOrigin-RevId: 840918430
2025-12-05 16:26:20 -08:00
Google Team Member f22bac0b20 feat: add Spanner execute sql query result mode
Add using the execute sql query return result as list of dictionaries.
In each dictionary the key is the column name and the value is the value of
the that column in a given row.

PiperOrigin-RevId: 840909555
2025-12-05 16:00:42 -08:00
George Weale de841a4a09 chore: Improve error message for missing invocation_id and new_message in run_async
Help with issue in #3801

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 840833736
2025-12-05 12:34:18 -08:00
Google Team Member b7ce5e17b6 fix: Yield event with error code when agent run raised A2AClientHTTPError
PiperOrigin-RevId: 840816236
2025-12-05 11:45:47 -08:00
Xuan Yang 9d2388a46f feat: Add SSL certificate verification configuration to OpenAPI tools
This change introduces a `verify` parameter to `RestApiTool` and `OpenAPIToolset`. This parameter allows users to configure how SSL certificates are verified when making API calls using the `requests` library. Options include providing a path to a CA bundle, disabling verification, or using a custom `ssl.SSLContext`. New methods `configure_verify` and `configure_verify_all` are added to update this setting after initialization. This is useful for environments with TLS-intercepting proxies.

Fixes: https://github.com/google/adk-python/issues/3720

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 840809727
2025-12-05 11:30:03 -08:00
Kacper Jawoszek 711df01e73 feat(otel): remove experimental status from otel_to_cloud
Co-authored-by: Kacper Jawoszek <jawoszek@google.com>
PiperOrigin-RevId: 840703872
2025-12-05 06:39:07 -08:00
Google Team Member a9b853fe36 fix: ApigeeLLM support for Built-in tools like GoogleSearch, BuiltInCodeExecutor when calling Gemini models through Apigee
PiperOrigin-RevId: 840459113
2025-12-04 16:57:30 -08:00
George Weale 3d444cc953 chore: Ignore the .adk/ directory
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 840387909
2025-12-04 13:54:17 -08:00
Google Team Member 82bd4f380b fix: Extract and propagate task_id in RemoteA2aAgent
The RemoteA2aAgent now extracts a "task_id" from the custom metadata of the last agent event in the session, alongside the existing "context_id". This task_id is then included in the A2AMessage sent to the remote A2A service.

Close #3765

PiperOrigin-RevId: 840375992
2025-12-04 13:25:46 -08:00
George Weale c557b0a1f2 fix: Update FastAPI and Starlette to fix CVE-2025-62727 (ReDoS vulnerability)
Update fastapi constraint from <0.119.0 to <0.124.0
Update starlette minimum version from >=0.46.2 to >=0.49.1

Closes #3822

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 840372879
2025-12-04 13:18:59 -08:00
davidkl97 f2735177f1 fix(oauth): add client id to token exchange
Merge https://github.com/google/adk-python/pull/2805

fixes #2806
add client id to token request, adhering to [RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3)

Co-authored-by: Xuan Yang <xygoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2805 from davidkl97:fix/oauth-exchange-token 3366dce65ce4dd4fee649a81ab7e486689637442
PiperOrigin-RevId: 840369113
2025-12-04 13:09:42 -08:00
George Weale 2b64715505 fix: Handle string function responses in LiteLLM conversion
When converting `types.Content` with a `function_response` to LiteLLM's `ChatCompletionToolMessage`, if the response is already a string, use it directly. Otherwise, serialize the response to JSON. This prevents double-serialization of string payloads

Close #3676

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 840013822
2025-12-03 19:17:16 -08:00
George Weale 0a07a667e9 feat: Change service creation and add app name mapping for sessions
This change refactors how session, memory, and artifact services are created in the fast_api server, using the shared service_factory.

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 839997110
2025-12-03 18:27:16 -08:00
Doug Reid e9182e5eb4 feat: Add Gemma3Ollama model integration and a sample
This change introduces `Gemma3Ollama`, a new LLM model class for running Gemma 3 models locally via Ollama, leveraging LiteLLM. The function calling logic previously in the `Gemma` class has been refactored into a `GemmaFunctionCallingMixin` and is now used by both `Gemma` and `Gemma3Ollama`. A new sample application, `hello_world_gemma3_ollama`, is added to demonstrate using `Gemma3Ollama` with an agent. Unit tests for `Gemma3Ollama` are also included.

Merge: https://github.com/google/adk-python/pull/3120

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 839996879
2025-12-03 18:27:07 -08:00
Lin-Nikaido b0c3cc6e36 fix: Support file uploads for OpenAI/Azure in LiteLLM
This change expands the supported file MIME types and introduces provider-specific handling for file uploads. For providers like OpenAI and Azure, inline file data is now uploaded via `litellm.acreate_file` to obtain a `file_id`, which is then used in the message content. Other providers continue to use base64 encoded file data. Affected functions have been updated to be asynchronous

Merge:https://github.com/google/adk-python/pull/2863

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 839996848
2025-12-03 18:26:27 -08:00
George Weale bb8a269079 fix: Extract and propagate task_id in RemoteA2aAgent
The RemoteA2aAgent now extracts a "task_id" from the custom metadata of the last agent event in the session, alongside the existing "context_id". This task_id is then included in the A2AMessage sent to the remote A2A service.

Close #3765

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 839996774
2025-12-03 18:25:41 -08:00
Łukasz Lipiński 507424acb9 feat: Add location for table in agent events in plugin BigQueryAgentAnalytics
Merge https://github.com/google/adk-python/pull/3784

Co-authored-by: Xuan Yang <xygoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3784 from lipinski:fix/add-location-to-bigqueryagentanalytics 8d88b2c3ad849b22e14a8d74185bfe348fd2503b
PiperOrigin-RevId: 839980070
2025-12-03 17:25:03 -08:00
Xuan Yang 92821b8dda docs: Remove the duplicated label instructions for the ADK triaging agent
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 839970998
2025-12-03 16:55:35 -08:00
Ankur Sharma 960b206752 chore: Bumps version to v1.20.0 and updates CHANGELOG.md
Co-authored-by: Ankur Sharma <ankusharma@google.com>
PiperOrigin-RevId: 839930279
2025-12-03 15:03:25 -08:00
Bo Yang 5947c41b55 chore: Update component owners
Co-authored-by: Bo Yang <ybo@google.com>
PiperOrigin-RevId: 839896507
2025-12-03 13:40:48 -08:00
Shangjie Chen 9d918d45df feat!: Rollback the DB migration as it is breaking
Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 839818479
2025-12-03 10:39:43 -08:00
George Weale 8c9105bf14 chore: Drop Python 3.9 support, set minimum to Python 3.10
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 839799108
2025-12-03 09:56:22 -08:00
George Weale e02b9fb608 fix: Add a warning when deploying with the ADK Web UI enabled
The warning message shows that ADK Web is for development purposes only and should not be used in production, as it has access to all data. This warning is displayed when the `--with-ui` flag is used with `adk deploy` and `adk deploy to-gke`

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 839795361
2025-12-03 09:47:13 -08:00
Rohit Yanamadala 76dc169a83 fix: Add editLimit parameter to GraphQL query
Merge https://github.com/google/adk-python/pull/3771

Co-authored-by: Xuan Yang <xygoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3771 from google:ryanaiagent-patch-1 a169e728af223594febc39299e046f2a195d606a
PiperOrigin-RevId: 839620767
2025-12-03 00:16:14 -08:00
Kathy Wu b638a48357 fix: Update API Registry Toolset to prod cloudapiregistry URL now that it is available
Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 839547174
2025-12-02 20:17:38 -08:00
Faraaz Ahmed b807d62fe3 feat(bigquery): Add labels support to BigQueryToolConfig for job tracking and monitoring
Merge https://github.com/google/adk-python/pull/3583

**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: #3582

**2. Or, if no issue exists, describe the change:**

_If applicable, please follow the issue templates to provide as much detail as
possible._

**Problem:**
Currently, the BigQuery tool in ADK does not provide a way for developers to add custom labels to BigQuery jobs created by their agents. This makes it difficult to:

Track and monitor BigQuery costs associated with specific agents or use cases
Organize and filter BigQuery jobs in the Google Cloud Console
Implement billing attribution and resource organization strategies
Differentiate between jobs from different environments (dev, staging, production)
While the tool automatically adds an internal adk-bigquery-tool label with the caller_id, there's no mechanism for users to add their own custom labels for tracking and monitoring purposes.

**Solution:**
Add a labels configuration field to BigQueryToolConfig that allows users to specify custom key-value pairs to be applied to all BigQuery jobs executed by the agent. The solution should:

Configuration Option: Add an optional labels parameter to BigQueryToolConfig accepting a dictionary of string key-value pairs
Validation: Ensure labels follow BigQuery's requirements (non-empty string keys, string values)
Job Application: Automatically apply configured labels to all BigQuery jobs alongside the existing internal labels Documentation: Provide clear documentation on how to use labels for tracking and monitoring

### 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:**

- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

_Please include a summary of passed `pytest` results._

```
pytest tests/unittests/tools/bigquery/test_bigquery_tool_config.py -v --tb=line -W ignore::UserWarning
========================================= test session starts ==========================================
platform darwin -- Python 3.11.14, pytest-9.0.1, pluggy-1.6.0 -- *****redacted******
cachedir: .pytest_cache
rootdir: *****redacted******
configfile: pyproject.toml
plugins: mock-3.15.1, anyio-4.11.0, xdist-3.8.0, langsmith-0.4.43, asyncio-1.3.0
asyncio: mode=Mode.AUTO, debug=False, asyncio_default_fixture_loop_scope=function, asyncio_default_test_loop_scope=function
collected 14 items

tests/unittests/tools/bigquery/test_bigquery_tool_config.py::test_bigquery_tool_config_experimental_warning PASSED                                                                                                   [  7%]
tests/unittests/tools/bigquery/test_bigquery_tool_config.py::test_bigquery_tool_config_invalid_property PASSED                                                                                                       [ 14%]
tests/unittests/tools/bigquery/test_bigquery_tool_config.py::test_bigquery_tool_config_invalid_application_name PASSED                                                                                               [ 21%]
tests/unittests/tools/bigquery/test_bigquery_tool_config.py::test_bigquery_tool_config_max_query_result_rows_default PASSED                                                                                          [ 28%]
tests/unittests/tools/bigquery/test_bigquery_tool_config.py::test_bigquery_tool_config_max_query_result_rows_custom PASSED                                                                                           [ 35%]
tests/unittests/tools/bigquery/test_bigquery_tool_config.py::test_bigquery_tool_config_valid_maximum_bytes_billed PASSED                                                                                             [ 42%]
tests/unittests/tools/bigquery/test_bigquery_tool_config.py::test_bigquery_tool_config_invalid_maximum_bytes_billed PASSED                                                                                           [ 50%]
tests/unittests/tools/bigquery/test_bigquery_tool_config.py::test_bigquery_tool_config_valid_labels PASSED                                                                                                           [ 57%]
tests/unittests/tools/bigquery/test_bigquery_tool_config.py::test_bigquery_tool_config_empty_labels PASSED                                                                                                           [ 64%]
tests/unittests/tools/bigquery/test_bigquery_tool_config.py::test_bigquery_tool_config_none_labels PASSED                                                                                                            [ 71%]
tests/unittests/tools/bigquery/test_bigquery_tool_config.py::test_bigquery_tool_config_invalid_labels_type PASSED                                                                                                    [ 78%]
tests/unittests/tools/bigquery/test_bigquery_tool_config.py::test_bigquery_tool_config_invalid_label_key_type PASSED                                                                                                 [ 85%]
tests/unittests/tools/bigquery/test_bigquery_tool_config.py::test_bigquery_tool_config_invalid_label_value_type PASSED                                                                                               [ 92%]
tests/unittests/tools/bigquery/test_bigquery_tool_config.py::test_bigquery_tool_config_empty_label_key PASSED                                                                                                        [100%]

==================================================================================================== 14 passed in 2.02s ====================================================================================================
```

**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

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.

### Additional context

_Add any other context or screenshots about the feature request here._

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3583 from Faraaz1994:feature/bq_label 0fd7fe6a3b1ee20a36f73562e425d007b8d7dc9d
PiperOrigin-RevId: 839523588
2025-12-02 19:15:20 -08:00
Xuan Yang 3aef9a18b1 docs: Update ADK issue triaging agent to add component label before planned
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 839391092
2025-12-02 12:54:44 -08:00
Shangjie Chen 77401132d1 chore: Add migration guide for DatabaseSessionService
Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 839376632
2025-12-02 12:15:52 -08:00
Google Team Member 090711934f feat: add Spanner vector_store_similarity_search tool
The vector_store_similarity_search tool performs similarity search against data in a Spanner vector store table, using the provided Spanner tool settings for configuration.

PiperOrigin-RevId: 839352057
2025-12-02 11:18:57 -08:00
Hangfei Lin 8da61be45a fix: Flush pending transcriptions on turn/generation complete or interrupt for Gemini API
The Gemini API may not always send an explicit transcription finished signal. This change ensures that any buffered input or output transcription text is yielded as a finished transcription when a turn is completed, generation is complete, or the session is interrupted.

Also, refined the check for `event.partial` in runners.py to be more explicit.

Co-authored-by: Hangfei Lin <hangfei@google.com>
PiperOrigin-RevId: 839008606
2025-12-01 18:09:29 -08:00
George Weale 98d82935e6 fix: allow LlmAgent model to be provided via CodeConfig
LlmAgentConfig.model now accepts either a plain model string or a CodeConfig. This lets YAML configs pass a LiteLLM instance with managed API settings (e.g., api_base and fallbacks) so agents can hit KimiK2’s managed endpoint instead of only the default modelID.

Close #3579

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 838978654
2025-12-01 16:31:22 -08:00
George Weale 7e8eeca6aa fix: Add a FastAPI endpoint for saving artifacts
This change adds new `POST` endpoint `/apps/{app_name}/users/{user_id}/sessions/{session_id}/artifacts` to the ADK web server. This endpoint lets clients to save new artifacts associated with a specific session. The endpoint uses `SaveArtifactRequest` and returns `SaveArtifactResponse`, including the version and canonical URI of the saved artifact.

Close #1975

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 838977880
2025-12-01 16:29:18 -08:00
George Weale ed9da3fa45 feat!: Introduction of ADK folder for local session and artifact storage
Default CLI session storage to SQLite instead of in-memory

Previously, adk run and adk web used in-memory session storage by default, causing sessions to be lost on restart. Now sessions persist to .adk/session.db automatically. To use in-memory storage, pass --session-service-uri memory://

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 838975328
2025-12-01 16:22:35 -08:00
Keyur Joshi dd827af2ee chore: Move simulation related modules to a sub-package in evaluation
Co-authored-by: Keyur Joshi <keyurj@google.com>
PiperOrigin-RevId: 838904075
2025-12-01 13:16:12 -08:00
Rohit Yanamadala cb19d0714c fix: Optimize Stale Agent with GraphQL and Search API to resolve 429 Quota errors
Merge https://github.com/google/adk-python/pull/3700

### Description
This PR refactors the `adk_stale_agent` to address `429 RESOURCE_EXHAUSTED` errors encountered during workflow execution. The previous implementation was inefficient in fetching issue history (using pagination over the REST API) and lacked server-side filtering, causing excessive API calls and huge token consumption that breached Gemini API quotas.

The new implementation switches to a **GraphQL-first approach**, implements server-side filtering via the Search API, adds robust concurrency controls, and significantly improves code maintainability through modular refactoring.

### Root Cause of Failure
The previous workflow failed with the following error due to passing too much context to the LLM and processing too many irrelevant issues:
```text
google.genai.errors.ClientError: 429 RESOURCE_EXHAUSTED.
Quota exceeded for metric: generativelanguage.googleapis.com/generate_content_paid_tier_input_token_count
```
### Key Changes

#### 1. Optimization: REST → GraphQL (`agent.py`)
*   **Old:** Fetched issue comments and timeline events using multiple paginated REST API calls (`/timeline`).
*   **New:** Implemented `get_issue_state` using a single **GraphQL** query. This fetches comments, `userContentEdits`, and specific timeline events (Labels, Renames) in one network request.
*   **Refactoring:** The complex analysis logic has been decomposed into focused helper functions (_fetch_graphql_data, _build_history_timeline, _replay_history_to_find_state) for better readability and testing.
*   **Configurable:** Added GRAPHQL_COMMENT_LIMIT and GRAPHQL_TIMELINE_LIMIT settings to tune context depth
*   **Impact:** Drastically reduces the data payload size and eliminates multiple API round-trips, significantly lowering the token count sent to the LLM.

#### 2. Optimization: Server-Side Filtering (`utils.py`)
*   **Old:** Fetched *all* open issues via REST and filtered them in Python memory.
*   **New:** Uses the GitHub Search API (`get_old_open_issue_numbers`) with `created:<DATE` syntax.
*   **Impact:** Only fetches issue numbers that actually meet the age threshold, preventing the agent from wasting cycles and tokens on brand-new issues.

#### 3. Concurrency & Rate Limiting (`main.py` & `settings.py`)
*   **Old:** Sequential execution loop.
*   **New:** Implemented `asyncio.gather` with a configurable `CONCURRENCY_LIMIT` (set to 3).
*   **New:** Added `urllib3` retry strategies (exponential backoff) in `utils.py` to handle GitHub API rate limits (HTTP 429) gracefully.

#### 4. Logic Improvements ("Ghost Edits")
*   **New Feature:** The agent now detects "Ghost Edits" (where an author updates the issue description without posting a new comment).
*   **Action:** If a silent edit is detected on a stale candidate, the agent now alerts maintainers instead of marking it stale, preventing false positives.

### File Comparison Summary

| File | Change |
| :--- | :--- |
| `main.py` | Switched from `InMemoryRunner` loop to `asyncio` chunked processing. Added execution timing and API usage logging. |
| `agent.py` | Replaced REST logic with GraphQL query. Added logic to handle silent body edits. Decomposed giant get_issue_state into helper functions with docstrings. Added _format_days helper. |
| `utils.py` | Added `HTTPAdapter` with Retries. Added `get_old_open_issue_numbers` using Search API. |
| `settings.py` | Removed `ISSUES_PER_RUN`; added configuration for CONCURRENCY_LIMIT, SLEEP_BETWEEN_CHUNKS, and GraphQL limits. |
| `PROMPT_INSTRUCTIONS.txt` | Simplified decision tree; removed date calculation responsibility from LLM. |

### Verification
The new logic minimizes token usage by offloading date calculations to Python and strictly limiting the context passed to the LLM to semantic intent analysis (e.g., "Is this a question?").

*   **Metric Check:** The workflow now tracks API calls per issue to ensure we stay within limits.
*   **Safety:** Silent edits by users now correctly reset the "Stale" timer.
*   **Maintainability:** All complex logic is now isolated in typed helper functions with comprehensive docstrings.

Co-authored-by: Xuan Yang <xygoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3700 from ryanaiagent:feat/improve-stale-agent 888064eff125ae74f7c3a9ad6c74f98de80243a2
PiperOrigin-RevId: 838885530
2025-12-01 12:25:51 -08:00
Ankur Sharma 2a1a41d3ec chore: Adding Eval Client label to model calls made during evals
Co-authored-by: Ankur Sharma <ankusharma@google.com>
PiperOrigin-RevId: 838857867
2025-12-01 11:20:46 -08:00
Eitan Yarmush 8e82838f1e fix: Refactor Anthropic integration to support both direct API and Vertex AI
This change introduces an `AnthropicLlm` base class for direct Anthropic API calls using `AsyncAnthropic`. The existing `Claude` class now inherits from `AnthropicLlm` and is specialized to use `AsyncAnthropicVertex` for models hosted on Vertex AI. The `messages.create` call is now properly awaited

Merge: https://github.com/google/adk-python/pull/2904

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 838851026
2025-12-01 11:04:51 -08:00
Ishan Raj Singh 7edd7ea9b7 chore: Add warning for full resource path in VertexAiMemoryBankService agent_engine_id
This change updates the docstring for `agent_engine_id` to clarify that only the resource ID is expected. It also adds a warning log if the provided `agent_engine_id` contains a '/' character, suggesting it might be a full resource path, and provides guidance on how to extract the ID. Unit tests are added to verify the warning behavior.

Merge: https://github.com/google/adk-python/pull/2941

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 838845022
2025-12-01 10:51:47 -08:00
Shangjie Chen 0094eea3ca feat!: Migrate DatabaseSessionService to use JSON serialization schema
Also provide a command line tool `adk migrate session` for DB migration

Addresses https://github.com/google/adk-python/discussions/3605
Addresses https://github.com/google/adk-python/issues/3681

To verify:
```
# Start one postgres DB
docker run --name my-postgres -d -e POSTGRES_DB=agent  -e POSTGRES_USER=agent  -e POSTGRES_PASSWORD=agent  -e PGDATA=/var/lib/postgresql/data/pgdata -v pgvolume:/var/lib/postgresql/data -p 5532:5432 postgres

# Connect to an old version of ADK and produce some query data
adk web --session_service_uri=postgresql://agent:agent@localhost:5532/agent

# Check out to the latest branch and restart ADK web
# You should see error log ask you to migrate the DB

# Start a new DB
docker run --name migration-test-db \
  -d \ --rm \ -e POSTGRES_DB=agent \ -e POSTGRES_USER=agent \ -e POSTGRES_PASSWORD=agent -e PGDATA=/var/lib/postgresql/data/pgdata -v migration_test_vol:/var/lib/postgresql/data -p 5533:5432 postgres

# DB Migration
adk migrate session \
  --source_db_url="postgresql://agent:agent@localhost:5532/agent" \
  --dest_db_url="postgresql://agent:agent@localhost:5533/agent"

# Run ADK web with the new DB
adk web --session_service_uri=postgresql+asyncpg://agent:agent@localhost:5533/agent

# You should see the data from old DB is migrated
```

Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 837341139
2025-11-26 19:49:08 -08:00
Xuan Yang 786aaed335 feat: Support streaming function call arguments in progressive SSE streaming feature
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 837172244
2025-11-26 10:15:31 -08:00
George Weale 73e5687b9a fix: Remove 'per_agent' from kwargs when using remote session service URIs
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 837169299
2025-11-26 10:08:13 -08:00
Kathy Wu ec4ccd718f feat: Create APIRegistryToolset to add tools from Cloud API registry to agent
This calls the cloudapiregistry.googleapis.com API to get MCP tools from the project's registry, and adds them to ADK.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 837166909
2025-11-26 10:01:58 -08:00
George Weale f283027e92 feat: expose service URI flags
Adds the shared adk_services_options decorator to adk run and other commands so developers can pass session/artifact URIs from the CLI

Has new warning for the unsupported memory service on adk run, and removes the legacy --session_db_url/--artifact_storage_uri flags with tests

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 836743358
2025-11-25 11:13:03 -08:00
George Weale 06e6fc9132 feat: wire runtime entrypoints to service factory defaults
This change routes adk run and the FastAPI server through the new session/artifact service factory, keeps the default experience backed by per-agent .adk storage

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 836733234
2025-11-25 10:47:44 -08:00
happyryan 5453b5bfde fix: Allow image parts in user messages for Anthropic Claude
Previously, image parts were always filtered out when converting content to Anthropic message parameters. This change updates the logic to only filter out image parts and log a warning when the content role is not "user". This enables sending image data as part of user prompts to Claude models

Merges: https://github.com/google/adk-python/pull/3286

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 836725196
2025-11-25 10:30:08 -08:00
Hangfei Lin 5cad8a7f58 fix: Throw warning when using transparent session resumption in ADK Live for Gemini API key
transparent session resumption is only supported in Vertex AI APIs

Co-authored-by: Hangfei Lin <hangfei@google.com>
PiperOrigin-RevId: 836715170
2025-11-25 10:04:57 -08:00
Virtuoso633 d29261a3dc feat(models): Enable multi-provider support for Claude and LiteLLM
Merges: https://github.com/google/adk-python/pull/2810

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 836706608
2025-11-25 09:46:44 -08:00
Bastien Jacot-Guillarmod e6be5bc9c6 fix: Add type annotations to Runner.__aenter__
PiperOrigin-RevId: 836614561
2025-11-25 04:45:00 -08:00
Om Kute c6e7d6b16a feat(tools): Add debug logging to VertexAiSearchTool
Merge https://github.com/google/adk-python/pull/3284

**Problem:**
When debugging agents that utilize the `VertexAiSearchTool`, it's currently difficult to inspect the specific configuration parameters (datastore ID, engine ID, filter, max_results, etc.) being passed to the underlying Vertex AI Search API via the `LlmRequest`. This lack of visibility can hinder troubleshooting efforts related to tool configuration.

**Solution:**
This PR enhances the `VertexAiSearchTool` by adding a **debug-level log statement** within the `process_llm_request` method. This log precisely records the parameters being used for the Vertex AI Search configuration just before it's appended to the `LlmRequest`.

This provides developers with crucial visibility into the tool's runtime behavior when debug logging is enabled, significantly improving the **debuggability** of agents using this tool. Corresponding unit tests were updated to rigorously verify this new logging output using `caplog`. Additionally, minor fixes were made to the tests to resolve Pydantic validation errors.

Co-authored-by: Xuan Yang <xygoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3284 from omkute10:feat/add-logging-vertex-search-tool 199c12bf00a57abe202401591088c0423b39b928
PiperOrigin-RevId: 836419886
2025-11-24 17:29:50 -08:00
Xuan Yang b331d97dfb docs: Remove the list_unlabeled_issues tool from the issue triaging agent
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 836416597
2025-11-24 17:14:51 -08:00
qieqieplus 4a42d0d9d8 feat: Add enum constraint to agent_name for transfer_to_agent
Merge https://github.com/google/adk-python/pull/2437

Current implementation of `transfer_to_agent` doesn't enforce strict constraints on agent names, we could use JSON Schema's enum definition to implement stricter constraints.

Co-authored-by: Xuan Yang <xygoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2437 from qieqieplus:main 052e8e73b9d61c0998573a2077f15864873d0dd7
PiperOrigin-RevId: 836410397
2025-11-24 16:51:36 -08:00
Shangjie Chen 728abe4d81 feat(agents): Add warning for duplicate sub-agent names
Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 836409638
2025-11-24 16:48:45 -08:00
Google Team Member 4eb2a11403 fix: fix bug where remote a2a agent wasn't using its a2a part converter
PiperOrigin-RevId: 836399603
2025-11-24 16:18:18 -08:00
Kristen Pereira a1c09b724b fix: Windows Path Handling and Normalize Cross-Platform Path Resolution in AgentLoader
Merge https://github.com/google/adk-python/pull/3609

Co-authored-by: George Weale <gweale@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3609 from p-kris10:fix/windows-cmd 8cb0310bd4450097a0a7714eaac6521b6a447442
PiperOrigin-RevId: 836395714
2025-11-24 16:07:40 -08:00
AlexeyChernenkoPlato cf21ca3584 fix: double function response processing issue
Merge https://github.com/google/adk-python/pull/2588

## Description
Fixes an issue in `base_llm_flow.py` where, in Bidi-streaming (live) mode, the multi-agent structure causes duplicated responses after tool calling.

## Problem
In Bidi-streaming (live) mode, when utilizing a multi-agent structure, the leaf-level sub-agent and its parent agent both process the same function call response, leading to duplicate replies. This duplication occurs because the parent agent's live connection remains open while initiating a new connection with the child agent.

## Root Cause
The issue originated from the placement of agent transfer logic in the `_postprocess_live` method at lines 547-557. When a `transfer_to_agent` function call was made:

1. The function response was processed in `_postprocess_live`
2. A recursive call to `agent_to_run.run_live` was initiated
3. This prevented the closure of the parent agent's connection at line 175 of the `run_live` method, as that code path was never reached
4. Both the parent and child agents remained active, causing both to process subsequent function responses

## Solution
This PR addresses the issue by ensuring the parent agent's live connection is closed before initiating a new one with the child agent. Changes made:

**Connection Management**: Moved the agent transfer logic from `_postprocess_live` method to the `run_live` method, specifically:
- Removed agent transfer handling from lines 547-557 in `_postprocess_live`
- Added agent transfer handling after connection closure at lines 176-184 in `run_live`

**Code Refactoring**: The agent transfer now occurs in the proper sequence:
1. Parent agent processes the `transfer_to_agent` function response
2. Parent agent's live connection is properly closed (line 175)
3. New connection with child agent is initiated (line 182)
4. Child agent handles subsequent function calls without duplication

**Improved Flow Control**: This ensures that each agent processes function call responses without duplication, maintaining proper connection lifecycle management in multi-agent structures.

## Testing
To verify this fix works correctly:

1. **Multi-Agent Structure Test**: Set up a multi-agent structure with a parent agent that transfers to a child agent via `transfer_to_agent` function call
2. **Bidi-Streaming Mode**: Enable Bidi-streaming (live) mode in the configuration
3. **Function Call Verification**: Trigger a function call that results in agent transfer
4. **Response Monitoring**: Verify that only one response is generated (not duplicated)
5. **Connection Management**: Confirm that parent agent's connection is properly closed before child agent starts

**Expected Behavior**:
- Single function response per call
- Clean agent handoffs without connection leaks
- Proper connection lifecycle management

## Backward Compatibility
This change is **fully backward compatible**:
- No changes to public APIs or method signatures
- Existing single-agent flows remain unaffected
- Non-live (regular async) flows continue to work as before
- Only affects the internal flow control in live multi-agent scenarios

Co-authored-by: Hangfei Lin <hangfei@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2588 from AlexeyChernenkoPlato:fix/double-function-response-processing-issue 3339260a4e007251137d199bdcef0ddef4487b03
PiperOrigin-RevId: 835619170
2025-11-22 09:34:05 -08:00
Shangjie Chen a9a418ba87 fix: Remove distructive validation
Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 835466120
2025-11-21 20:56:39 -08:00
George Weale 2e1f730c3b fix: Update LiteLLM system instruction role from "developer" to "system"
This change replaces the use of `ChatCompletionDeveloperMessage` with `ChatCompletionSystemMessage` and sets the role to "system" for providing system instructions to LiteLLM models

Close #3657

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 835388738
2025-11-21 15:56:04 -08:00
Xuan Yang 52674e7fac fix: Update AgentTool to use Agent's description when input_schema is provided in FunctionDeclaration
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 835379243
2025-11-21 15:25:27 -08:00
davidkl97 777dba3033 feat(tools): Add an option to disallow propagating runner plugins to AgentTool runner
Merge https://github.com/google/adk-python/pull/2779

Fixes #2780

### testing plan
not available as is doesn't introduce new functionality

Co-authored-by: Wei Sun (Jack) <weisun@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2779 from davidkl97:feature/agent-tool-plugins a602c808789f3daeed6244e352a6fb8fb6972de3
PiperOrigin-RevId: 835366974
2025-11-21 14:49:36 -08:00
saroj rout 2247a45922 feat(agents): add validation for unique sub-agent names (#3557)
Merge https://github.com/google/adk-python/pull/3576

**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: #3557
- 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:**
When creating a BaseAgent with multiple sub-agents, there was no validation to ensure that all sub-agents have unique names. This could lead to confusion when trying to find or reference specific sub-agents by name, as duplicate names would make it ambiguous which agent is being referenced.
**Solution:**
Added a @field_validator for the sub_agents field in BaseAgent that validates all sub-agents have unique names. The validator:
Checks for duplicate names in the sub-agents list
Raises a ValueError with a clear error message listing all duplicate names found
Returns the validated list if all names are unique
Handles edge cases like empty lists gracefully

### 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:**

- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

_Please include a summary of passed `pytest` results._
Added 4 new test cases in tests/unittests/agents/test_base_agent.py:
test_validate_sub_agents_unique_names_single_duplicate: Verifies that a single duplicate name raises ValueError
test_validate_sub_agents_unique_names_multiple_duplicates: Verifies that multiple duplicate names are all reported in the error message
test_validate_sub_agents_unique_names_no_duplicates: Verifies that unique names pass validation successfully
test_validate_sub_agents_unique_names_empty_list: Verifies that empty sub-agents list passes validation
All tests pass locally. You can run with:
pytest tests/unittests/agents/test_base_agent.py::test_validate_sub_agents_unique_names_single_duplicate tests/unittests/agents/test_base_agent.py::test_validate_sub_agents_unique_names_multiple_duplicates tests/unittests/agents/test_base_agent.py::test_validate_sub_agents_unique_names_no_duplicates tests/unittests/agents/test_base_agent.py::test_validate_sub_agents_unique_names_empty_list -v
**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._

Test Case 1: Duplicate names should raise error
from google.adk.agents import Agent

agent1 = Agent(name="sub_agent", model="gemini-2.5-flash")
agent2 = Agent(name="sub_agent", model="gemini-2.5-flash")  # Same name

# This should raise ValueError
try:
    parent = Agent(
        name="parent",
        model="gemini-2.5-flash",
        sub_agents=[agent1, agent2]
    )
except ValueError as e:
    print(f"Expected error: {e}")
    # Output: Found duplicate sub-agent names: `sub_agent`. All sub-agents must have unique names.

Test Case 2: Unique names should work
from google.adk.agents import Agent

agent1 = Agent(name="agent1", model="gemini-2.5-flash")
agent2 = Agent(name="agent2", model="gemini-2.5-flash")

# This should work without error
parent = Agent(
    name="parent",
    model="gemini-2.5-flash",
    sub_agents=[agent1, agent2]
)
print("Success: Unique names validated correctly")

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.

### Additional context

This change adds validation at the BaseAgent level, so it automatically applies to all agent types that inherit from BaseAgent (e.g., LlmAgent, LoopAgent, etc.). The validation uses Pydantic's field validator system, which runs during object initialization, ensuring the constraint is enforced early and consistently.
The error message clearly identifies which names are duplicated, making it easy for developers to fix the issue:

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3576 from sarojrout:feat/validate-unique-sub-agent-names 07adf1f9a5fc935389eb9dfa3cbc1311f551ebe3
PiperOrigin-RevId: 835358118
2025-11-21 14:24:07 -08:00
Adrian Altermatt 609c6172d9 docs: too many E(inv=2, role=user) plus reformatting
Merge https://github.com/google/adk-python/pull/3538

Main change from:
E(inv=2, role=user), E(inv=2, role=model), E(inv=2, role=user),

To:
E(inv=2, role=user), E(inv=2, role=model)

I think the last E(inv=2, role=user) was wrong. Also reformatted.

Co-authored-by: Hangfei Lin <hangfei@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3538 from adrianad:patch-1 627b933bdc3e00e45f704edf95448281e32d127c
PiperOrigin-RevId: 835346467
2025-11-21 13:49:01 -08:00
Giorgio Boa 9d331abb4e ci: bump action scripts versions
Merge https://github.com/google/adk-python/pull/3638

Thanks for this great project 👏
This PR updates the GitHub actions dependencies to the latest version.

### Checklist

- [X] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [X] I have performed a self-review of my own code.

Co-authored-by: Hangfei Lin <hangfei@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3638 from gioboa:ci/actions-versions f7d6f3b5233e8cb135c8af88d5b6e0ead8382055
PiperOrigin-RevId: 835343177
2025-11-21 13:39:46 -08:00
Rohit Yanamadala 23f1d8914a docs(agent): Implement stale issue bot
Merge https://github.com/google/adk-python/pull/3546

Co-authored-by: Xuan Yang <xygoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3546 from ryanaiagent:feat/stale-issue-agent bcf45098c1c6406b4a42228e4a8ef02f12840425
PiperOrigin-RevId: 835327931
2025-11-21 12:54:20 -08:00
Shangjie Chen 5583bb819b chore: Update MCP requirement to >1.10.0
Resolves https://github.com/google/adk-python/issues/3644

Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 835302097
2025-11-21 11:43:32 -08:00
Shangjie Chen 89aee16f16 chore: Allow google-cloud-storage >=2.18.0
Resolves https://github.com/google/adk-python/issues/3641

Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 835292931
2025-11-21 11:18:40 -08:00
Max Ind a4453c884c fix: adk deploy agent_engine uses correct URI during an update
Co-authored-by: Max Ind <maxind@google.com>
PiperOrigin-RevId: 835269976
2025-11-21 10:17:57 -08:00
Google Team Member 11df1e886d fix: Change pass to yield in BaseLlmConnection.receive
PiperOrigin-RevId: 835268090
2025-11-21 10:12:19 -08:00
Austin Wise 59eba96ea4 fix: Remove unused, incorrect import
PiperOrigin-RevId: 835247166
2025-11-21 09:10:04 -08:00
Google Team Member 631b58336d fix: Content is marked non empty if its first part contains text or inline_data or file_data or func call/response
PiperOrigin-RevId: 835063599
2025-11-20 22:19:28 -08:00
George Weale a3e4ad3cd1 fix: Update session last update time when appending events
The `database_session_service` now updates the `update_time` of a session to the event's timestamp when an event is appended

Close #2721

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 834994070
2025-11-20 18:27:02 -08:00
George Weale 848fdbef7c fix: Filter out None values from enum lists in schema generation
Close #3552

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 834967220
2025-11-20 17:02:45 -08:00
George Weale 31cfa3b82b feat: Capture thinking output, forward raw payloads, and fix exec locals
LlmResponse/Event now keep both provider reasoning output and the raw vendor payload so callbacks and loggers can inspect hidden “thoughts” or trace bugs without rewriting adapters.

LiteLLM’s adapter and streaming loop emit reasoning chunks alongside text and aggregate them into final events -> all responses now carry a JSON-safe copy of the source payload for debug. UnsafeLocalCodeExecutor uses the documented exec(code, globals, globals) form, letting helper functions defined inside snippets call each other.

Close #1749

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 834956847
2025-11-20 16:30:19 -08:00
Dylan b57fe5f459 feat(web): add list-apps-detailed endpoint
Merge https://github.com/google/adk-python/pull/3430

**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: #3429

**2. Or, if no issue exists, describe the change:**

_If applicable, please follow the issue templates to provide as much detail as
possible._

**Problem:**
The existing `/list-apps` endpoint only returns the name of the folder that each agent is in

**Solution:**
This adds a new endpoint `/list-apps-detailed` which will load each agent using the existing `AgentLoader.load_agent` method, and then return the folder name, display name (with underscores replaced with spaces for a more readable version), description, and the agent type.

This does introduce overhead if you had multiple agents since they all need to be loaded, but by maintaining the existing `/list-apps` endpoint, users can choose which one to hit if they don't want to load all agents. Since the existing `load_agents` method will cache results, there's only a penalty on the first hit.

### Testing Plan

Created a unit test for this, similar to the `/list-apps`. Also tested this with my own ADK instance to verify it loaded correctly.
```
curl --location "localhost:8000/list-apps-detailed"
```
```json
{
    "apps": [
        {
            "name": "agent_1",
            "displayName": "Agent 1",
            "description": "A test description for a test agent",
            "agentType": "package"
        },
        {
            "name": "agent_2",
            "displayName": "Agent 2",
            "description": "A test description for a test agent ",
            "agentType": "package"
        },
        {
            "name": "agent_3",
            "displayName": "Agent 3",
            "description": "A test description for a test agent",
            "agentType": "package"
        }
    ]
}

```

**Unit Tests:**

- [X] I have added or updated unit tests for my change.
- [X] All unit tests pass locally.

 3054 passed, 2383 warnings in 46.96s

### Checklist

- [X] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [X] I have performed a self-review of my own code.
- [X] I have commented my code, particularly in hard-to-understand areas.
- [X] I have added tests that prove my fix is effective or that my feature works.
- [X] New and existing unit tests pass locally with my changes.
- [X] I have manually tested my changes end-to-end.
- [X] Any dependent changes have been merged and published in downstream modules.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3430 from dylan-apex:more-detailed-list-apps e6864fd61a673da5fd2fb28d2d7d72cb90f5af0a
PiperOrigin-RevId: 834907771
2025-11-20 14:15:06 -08:00
Issac cd54f48fed fix: fix paths for public docs
Merge https://github.com/google/adk-python/pull/3572

**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):**

N/A

**2. Or, if no issue exists, describe the change:**

**Problem:**
Docs 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.

Co-authored-by: Hangfei Lin <hangfei@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3572 from issacg:patch-1 b7c7ed46ff0fb018f4da1537535eff27c323daf5
PiperOrigin-RevId: 834864431
2025-11-20 12:26:43 -08:00
George Weale 084c2de0da fix: Make sure request bodies without explicit names are named 'body'
The `Parameter` class now provides default Python names based on the parameter location when the original name is empty. This prevents parameters from having an empty string as their Python name, especially for request bodies defined without a top-level name.

Close #2213

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 834850255
2025-11-20 11:48:46 -08:00
George Weale bf8b85da52 fix: save sessions with camelCase aliases
Make sure that the adk run --save_session writes session JSON using the Pydantic camelCase aliases (by_alias=True), matching ADK Web and keeping session files consistent

Close #3558

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 834847209
2025-11-20 11:41:41 -08:00
Holt Skinner caf23ac49f docs: Add Code Wiki badge to README
Merge https://github.com/google/adk-python/pull/3603

**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._

Co-authored-by: Hangfei Lin <hangfei@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3603 from holtskinner:patch-1 833405898b747438e3f8a1b8c34095e25135fca3
PiperOrigin-RevId: 834805195
2025-11-20 10:00:29 -08:00
Kathy Wu a3aa07722a fix: Update the retry_on_closed_resource decorator to retry on all errors
Retrying only on closed_resource error is not enough to be reliable for production environments due to the other network errors that may occur -- remote protocol error, read timeout, etc. We will update this to retry on all errors. Since it is only a one-time retry, it should not affect latency significantly. Fixes https://github.com/google/adk-python/issues/2561.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 834514264
2025-11-19 17:50:49 -08:00
Shangjie Chen a6e4d6c0d9 chore: Bumps version to v1.19.0 and updates CHANGELOG.md
Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 834503873
2025-11-19 17:12:56 -08:00
Divyansh Shukla 8fc6128b62 fix: Fix out of bounds error in _run_async_impl
PiperOrigin-RevId: 834492696
2025-11-19 16:36:35 -08:00
Xuan Yang 679d543f8e docs: Update ADK triaging agent to only triage planned issues
It also enables the ADK triaging agent to run periodically on planned but not triaged issues.

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 834489103
2025-11-19 16:26:55 -08:00
Google Team Member f13a11e1dc feat: Propagate application_name set for the BigQuery Tools as BigQuery job labels
This change will help the tools user identify per agent job usage in BQ console and INFORMATION_SCHEMA views. This change fulfills the feature request #3582. Here is a demo after change: screen/C6YB4ge2FM2ZREi.

PiperOrigin-RevId: 834480140
2025-11-19 16:02:32 -08:00
George Weale 131d39c3db fix: Change name for builder agent
When this agent was built before the agent name was changed in the build script and accepted like that from the VB so changed to set into that form

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 834479335
2025-11-19 16:00:51 -08:00
George Weale 12db84f5cd fix: Remove app name from FileArtifactService directory structure
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 834462462
2025-11-19 15:12:48 -08:00
Ankur Sharma dc3f60cc93 chore: Plumb memory service from LocalEvalService to EvaluationGenerator
Co-authored-by: Ankur Sharma <ankusharma@google.com>
PiperOrigin-RevId: 834398581
2025-11-19 12:28:52 -08:00
Yifan Wang 14e3802643 chore: update adk web to match main branch
Co-authored-by: Yifan Wang <wanyif@google.com>
PiperOrigin-RevId: 834378696
2025-11-19 11:37:29 -08:00
Shangjie Chen ffbab4cf4e chore: Add BigQuery related label handling
Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 834375503
2025-11-19 11:29:40 -08:00
George Weale b2b7f2d6aa chore: Move adk_agent_builder_assistant to built_in_agents
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 834371390
2025-11-19 11:18:37 -08:00
Hangfei Lin 3ad30a58f9 fix: Add transcription fields to session events
This change introduces `input_transcription` and `output_transcription` fields to session events, enabling the storage and retrieval of transcription data in both the database and Vertex AI session services.

Closes #3172

Co-authored-by: Hangfei Lin <hangfei@google.com>
PiperOrigin-RevId: 834366848
2025-11-19 11:08:38 -08:00
George Weale 0ac35b23dc docs: Add path sanitization for model-generated file paths
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 834344352
2025-11-19 10:13:16 -08:00
Mimi Sun 857de04deb feat: update save_files_as_artifacts_plugin to never keep inline data
PiperOrigin-RevId: 834328794
2025-11-19 09:36:42 -08:00
Max Ind e15e19da05 fix: remove hardcoded google-cloud-aiplatform version in agent engine requirements
This fixes e.g. `--trace_to_cloud flag`

Co-authored-by: Max Ind <maxind@google.com>
PiperOrigin-RevId: 834190152
2025-11-19 02:01:34 -08:00
Michael Jones 0cc3d6d6d5 Feat/expose mcps streamable http custom httpx factory parameter (#2997)
* feat: Add support for custom HTTPX client factory in StreamableHTTPConnectionParams

* Update src/google/adk/tools/mcp_tool/mcp_session_manager.py

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* unit tested mock

* provide default - httpx client factory can't be none

* feat: Enhance StreamableHTTPConnectionParams with httpx_client_factory attribute

* fmt

* fmt

* refactor: Rename test_init_with_streamable_http_none_httpx_factory to test_init_with_streamable_http_default_httpx_factory for clarity

* isort

* fmt

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Kathy Wu <108756731+wukath@users.noreply.github.com>
2025-11-18 11:09:48 -08:00
Hangfei Lin b5f5df9fa8 fix(runners): Ensure event compaction completes by awaiting task
Fixes https://github.com/google/adk-python/issues/3174

The event compaction process, configured via `EventsCompactionConfig`, was
previously scheduled as a background task using `asyncio.create_task`.
Because Python's `asyncio.create_task` only holds a weak reference to
the created task and no strong reference was maintained by ADK, the
compaction task could be garbage-collected before it finished executing.
This resulted in event compaction failing silently or only partially
running, preventing session history from being summarized.

### Approaches Considered

Two approaches were considered to fix this:

1.  **`asyncio.create_task` + Reference:** Create the task with `create_task` and store a strong reference to it (e.g., in a `set` on the [Runner](http://_vscodecontentref_/0) instance), removing it only when complete via `task.add_done_callback()`.
    *   **Pros:** The [run_async](http://_vscodecontentref_/1) async generator finishes immediately after yielding the last agent event.
    *   **Cons:** Adds complexity to the Runner state; background task failures are silent to the [run_async](http://_vscodecontentref_/2) caller; requires enhancement to `runner.close()` to correctly manage pending tasks on shutdown.
2.  **`await`:** Directly `await` the compaction coroutine at the end of [run_async](http://_vscodecontentref_/3) after all agent events have been yielded.
    *   **Pros:** Simple to implement; ensures compaction runs to completion; failures during compaction propagate immediately to the [run_async](http://_vscodecontentref_/4) caller, making them visible and easier to debug.
    *   **Cons:** The `async for` loop iterating over [run_async](http://_vscodecontentref_/5) will not terminate until compaction finishes.

### Decision

This change implements the `await` approach. Although it means the `async for` loop takes longer to terminate when compaction occurs, it was chosen for its **simplicity and robustness**. Ensuring that compaction either succeeds or fails visibly is preferable to silent background failures.

All agent response events are yielded *before* compaction starts, so there is **no user-perceived delay in receiving the agent's answer** for the current turn.

### Integration Note for Users

Because compaction is now awaited, code consuming events via `async for event in runner.run_async(...)` will only finish iterating *after* compaction is complete (if compaction is triggered for that invocation).

If your application only needs the agent's response to proceed (e.g., displaying a message in a UI and allowing the user to reply), you can process events as they arrive and initiate the next turn without waiting for the `async for` loop to fully terminate. A new call to [run_async](http://_vscodecontentref_/6) for the next user query can be made immediately and will execute concurrently.

**Example:**

```python
async def handle_agent_turn(runner, message):
    print("Agent is thinking...")
    async for event in runner.run_async(user_id='...', session_id='...', new_message=message):
        # Stream events to UI, log, etc.
        if event.author == 'model' and event.content and event.content.parts[0].text:
            print(f"Agent response: {event.content.parts[0].text}")
            # The agent has provided a text response.
            # The application can now enable user input for the next turn,
            # even though this async for loop might not finish immediately
            # if compaction is running.
    print("Invocation complete (including compaction if any).")

# In your application:
# A new call to handle_agent_turn(runner, next_message) can be made
# as soon as the user provides the next input, without waiting for
# the previous call's generator to be exhausted.

Co-authored-by: Hangfei Lin <hangfei@google.com>
PiperOrigin-RevId: 833885375
2025-11-18 10:57:50 -08:00
George Weale a12ae812d3 feat: Add service factory for configurable session and artifact backends
this creates service_factory to handle .adk folder changes (including per-agent .adk defaults and in-memory/custom URI handling)

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 833875524
2025-11-18 10:35:31 -08:00
Shangjie Chen 8eb1bdbc58 chore: Add demo for rewind
Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 833871446
2025-11-18 10:26:15 -08:00
George Weale 236f562cd2 fix: Load agent/app before creating session
This change loads the agent or app from the specified directory before creating the session. This allows using the correct application name (from the `App` object if applicable) when initializing the session, rather than always defaulting to the folder name. The variable `root_agent` is also renamed to `agent_or_app` to better reflect that it can be either an Agent or an App

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 833839070
2025-11-18 09:09:22 -08:00
Google Team Member 4dd28a3970 feat: Add id and custom_metadata fields to MemoryEntry
PiperOrigin-RevId: 833581243
2025-11-17 18:34:03 -08:00
Ankur Sharma b2c45f8d91 chore: Enhance the messaging with possible fixes for RESOURCE_EXHAUSTED errors from Gemini
Co-authored-by: Ankur Sharma <ankusharma@google.com>
PiperOrigin-RevId: 833538475
2025-11-17 16:15:56 -08:00
Google Team Member 5ac5129fb0 feat: Enhance BQ Plugin Schema, Error Handling, and Logging
This update enhances the BigQuery agent analytics plugin:

*   **Enhanced Error Logging:** Improved error messages for schema mismatches.
*   **Reordered Logging Content:** Prioritized metadata in `before_model_callback`.

PiperOrigin-RevId: 833508755
2025-11-17 15:00:38 -08:00
Google Team Member c642f13f21 feat: Thread custom_metadata through forwarding artifact service
PiperOrigin-RevId: 833496193
2025-11-17 14:25:30 -08:00
Kathy Wu a48a1a9e88 fix: Improve logic for checking if a MCP session is disconnected
Currently logic to check for a disconnected session only checks for certain headers but doesn't detect all cases, leading to situations where it tries to connect to a session that is down. This adds logic so that we ping the server to check if it is disconnected. Fixes https://github.com/google/adk-python/issues/3321.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 833487825
2025-11-17 14:05:02 -08:00
Xuan Yang a5ac1d5e14 feat: Add progressive SSE streaming feature
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 833483804
2025-11-17 13:55:38 -08:00
George Weale 0ec01956e8 fix: keep vertex session event history intact
Close #3504

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 833417574
2025-11-17 11:13:08 -08:00
George Weale 840283228e feat!: Raise minimum Python version to 3_10
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 833363352
2025-11-17 09:02:58 -08:00
Xuan Yang 1dd97f5b45 fix: Add experimental feature to use parameters_json_schema and response_json_schema for McpTool
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 833144947
2025-11-16 20:55:16 -08:00
Wei Sun (Jack) f7f6837fde docs: Add python tips to AGENTS.md to assist vibe coding
Co-authored-by: Wei Sun (Jack) <weisun@google.com>
PiperOrigin-RevId: 832772144
2025-11-15 14:08:04 -08:00
George Weale 2dea5733b7 fix: add type hints in cleanup_unused_files.py
Updates type annotations to use built-in types like `list` and `dict`, and uses `| None` for optional types, along with adding `from __future__ import annotations`

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 832522395
2025-11-14 17:58:37 -08:00
Xuan Yang 871da731f1 feat: Add feature decorator for the feature registry system
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 832503990
2025-11-14 16:48:09 -08:00
Shangjie Chen 9211f4ce8c fix: Use async for to loop through event iterator to get all events in vertex_ai_session_service
Fix https://github.com/google/adk-python/issues/3559

Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 832476367
2025-11-14 15:22:27 -08:00
Kathy Wu a754c96d3c fix: Improve logic for checking if a MCP session is disconnected
Currently logic to check for a disconnected session only checks for certain headers but doesn't detect all cases, leading to situations where it tries to connect to a session that is down. This adds logic so that we ping the server to check if it is disconnected. Fixes https://github.com/google/adk-python/issues/3321.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 832460068
2025-11-14 14:33:39 -08:00
anrzeszutek 29fea7ec1f fix: Fix deploy to cloud run on Windows
Merge https://github.com/google/adk-python/pull/3536

- Closes: #1597
- Related: #3306

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3536 from anrzeszutek:main ab9f6bfcd51b373934c0c03ef41c880ce224b31d
PiperOrigin-RevId: 832441843
2025-11-14 13:41:58 -08:00
Google Team Member 7c993b01d1 feat: Schema Enhancements with Descriptions, Partitioning, and Truncation Indicator
This update enhances the BigQuery agent analytics plugin:

*   **Schema Field Descriptions:** The recommended BigQuery table schema now includes descriptions for each field, improving data understandability.
*   **Optimized Table Structure:** The plugin now creates the table with daily partitioning on `timestamp` and clustering on `event_type`, `agent`, and `user_id` by default.
*   **Truncation Flag:** A new boolean field `is_truncated` is added to the schema to show if the `content` was truncated.

PiperOrigin-RevId: 832436799
2025-11-14 13:28:45 -08:00
Ankur Sharma 696852a280 chore: Add default retry options as fall back to llm_request that are made during evals
In order to make evals more resilient to temporary model failures, we add retry options to llm_requests that are made during evals.

Note that this is a fall back option, if the developer has already specified their own retry options, then those will be honored.

Co-authored-by: Ankur Sharma <ankusharma@google.com>
PiperOrigin-RevId: 832383755
2025-11-14 11:02:54 -08:00
milkisbad 9b754564b3 fix: status code in error message in RestApiTool
Merge https://github.com/google/adk-python/pull/2819

add status code to http error to make it more verbose

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

# testing plan
run new tests that have beed added in PR

Co-authored-by: Hangfei Lin <hangfei@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2819 from milkisbad:rest_api_tool_verbose_error 79ac6d96174d414e7ca958379102cfa7ede0e883
PiperOrigin-RevId: 832367374
2025-11-14 10:24:21 -08:00
George Weale 0fa7e4619d fix: Add jsonschema dependency for Agent Builder config validation
Close #3494

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 832362832
2025-11-14 10:10:30 -08:00
Google Team Member b7d571bc3f chore: make readability improvements in ADK BQ tool tests
PiperOrigin-RevId: 832110063
2025-11-13 19:43:25 -08:00
Google Team Member 5adbf95a0a fix: stop updating write mode in the global settings during tool execution
Two tools - detect_anomalies and analyze_contribution are modifying the settings passed to them, which is not right as the settings are held and passed by the top level, which means several tools share the same settings.

PiperOrigin-RevId: 832081738
2025-11-13 18:02:19 -08:00
Xuan Yang 23ad40bad2 feat: Introduce a feature registry system for ADK
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 832050198
2025-11-13 16:14:49 -08:00
Yeesian Ng b8e4aedfbf fix: Add vertexai initialization for code being deployed to AgentEngine
Co-authored-by: Yeesian Ng <ysian@google.com>
PiperOrigin-RevId: 832031219
2025-11-13 15:23:24 -08:00
Google Team Member ffbb0b37e1 feat: allow setting max_billed_bytes in BigQuery tools config
This will allow users to configure a limit to access in ADK tools on the charges for queries.

PiperOrigin-RevId: 831921163
2025-11-13 10:42:56 -08:00
George Weale 22eb7e5b06 feat: Add support for parsing inline JSON tool calls in LiteLLM responses
Close #1968

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 831911719
2025-11-13 10:18:27 -08:00
Sara Robinson 2efc184a46 chore: Add support for abstract types in AFC
PiperOrigin-RevId: 831873580
2025-11-13 08:38:25 -08:00
Google Team Member 6bb0b7417e chore: Add abstract type annotation support to AFC
PiperOrigin-RevId: 831545133
2025-11-12 14:39:43 -08:00
Liang Wu 69627b699f chore: Implement lazy loading for modules within google.adk.tools
This is ~27% of the current cold start latency after previous changes are submitted. This change refactors `google.adk.tools/__init__.py` to use `__getattr__` for lazy loading of all tools and related classes. Previously, all modules were imported directly upon `google.adk.tools` import, leading to potentially long initial import times. With lazy loading, modules are only imported when they are first accessed, improving the initial startup performance.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 831537187
2025-11-12 14:17:26 -08:00
Hangfei Lin 0ab79b9502 fix: Deprecate save_live_audio in favor of save_live_blob and fix audio event saving
This change:
*   Deprecates the `save_live_audio` configuration option in `RunConfig`, introducing `save_live_blob` as its replacement. A warning is issued if `save_live_audio` is used.
*   Updates `base_llm_flow.py` to use the new `save_live_blob` flag.
*   Ensures that audio events generated by `audio_cache_manager.py` are properly appended to the session service.
*   Adds a utility script `pcm_audio_player.py` for playing raw PCM audio files.

Input sample event: 14a5859f-6b6c-46ed-9f28-e5008793b1c6|live_bidi_streaming_multi_agent|user|1e867c7f-dbe1-4268-a7bc-7a9fa5fbd16c|e-7a28a060-29bf-4483-bc5c-17248698a897|1762916981.5932|{"content":{"parts":[{"file_data":{"file_uri":"artifact://live_bidi_streaming_multi_agent/user/1e867c7f-dbe1-4268-a7bc-7a9fa5fbd16c/_adk_live/adk_live_audio_storage_input_audio_1762916981593.pcm#0","mime_type":"audio/pcm"}}],"role":"user"},"invocation_id":"e-7a28a060-29bf-4483-bc5c-17248698a897","author":"user","actions":{"state_delta":{},"artifact_delta":{},"requested_auth_configs":{},"requested_tool_confirmations":{}},"id":"14a5859f-6b6c-46ed-9f28-e5008793b1c6","timestamp":1762916981.5932002}

output sample event:
506c9df4-e143-4ebc-90a5-2f5b2eb26754|live_bidi_streaming_multi_agent|user|1e867c7f-dbe1-4268-a7bc-7a9fa5fbd16c|e-7a28a060-29bf-4483-bc5c-17248698a897|1762916986.10579|{"content":{"parts":[{"file_data":{"file_uri":"artifact://live_bidi_streaming_multi_agent/user/1e867c7f-dbe1-4268-a7bc-7a9fa5fbd16c/_adk_live/adk_live_audio_storage_output_audio_1762916986105.pcm;rate=24000#0","mime_type":"audio/pcm;rate=24000"}}],"role":"model"},"invocation_id":"e-7a28a060-29bf-4483-bc5c-17248698a897","author":"model","actions":{"state_delta":{},"artifact_delta":{},"requested_auth_configs":{},"requested_tool_confirmations":{}},"id":"506c9df4-e143-4ebc-90a5-2f5b2eb26754","timestamp":1762916986.105794}

Co-authored-by: Hangfei Lin <hangfei@google.com>
PiperOrigin-RevId: 831512074
2025-11-12 13:16:13 -08:00
George Weale 675ecaa8db feat!: Upgrade to include python3.14
pin crew ai to 3.13 at highest version as it uses chromadb and that uses onnxruntime which does not work yet with 3.14

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 831508884
2025-11-12 13:09:00 -08:00
Google Team Member d12468ee5a feat: add a2a_request_meta_provider to RemoteAgent init
The change adds an extension point for controlling which request metadata gets attached to A2A requests made by a RemoteAgent.
Instead of taking metadata from custom_metadata of session events users can construct payloads using a2a_request_meta_provider.

request_meta feature was added in v0.3.11 of the a2a-sdk library: https://github.com/a2aproject/a2a-python/releases/tag/v0.3.11

PiperOrigin-RevId: 831506364
2025-11-12 13:04:06 -08:00
Hangfei Lin 5d5708b2ab chore: Add debug logging for live connection
This CL adds debug logs to show the history being sent to the live connection and the live connect config used.

Co-authored-by: Hangfei Lin <hangfei@google.com>
PiperOrigin-RevId: 831473597
2025-11-12 11:36:08 -08:00
Sara Robinson 52b1dfea14 chore: Add abstract type annotation support to AFC
PiperOrigin-RevId: 831462920
2025-11-12 11:11:41 -08:00
Liang Wu 22c6dbe83c chore: Defer import of live, Client and _transformers in google.genai
Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 831444358
2025-11-12 10:27:56 -08:00
George Weale a19be12c1f fix: change LiteLLM content and tool parameter handling
This changes how content parts are converted for LiteLLM, treating all "text/" mime types as plain text and only "application/pdf" as a file

Close #1940

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 831418696
2025-11-12 09:23:00 -08:00
Ankur Sharma e2d3b2d862 feat: Added support for InOrder and AnyOrder match in ToolTrajectoryAvgScore Metric
Co-authored-by: Ankur Sharma <ankusharma@google.com>
PiperOrigin-RevId: 831413968
2025-11-12 09:10:34 -08:00
Google Team Member b2c8ba5806 chore: Defer import of live, Client and _transformers in google.genai
This is targeting the Client import mostly, but also prevents future latency increase if the other modules in genai adds more 3p dependencies. This change will make ADK only import `live`, `Client` and `_transformers` just-in-time, therefore cutting down cold start latency.

PiperOrigin-RevId: 831244349
2025-11-11 23:56:20 -08:00
Google Team Member 37ee1869b5 fix: Enhance BigQuery Plugin Robustness and Schema Accuracy
This update improves the `BigQueryAgentAnalyticsPlugin` in several ways:

*   Corrects the PyArrow schema generation to accurately reflect BigQuery field nullability based on the `mode` attribute.
*   Introduces a configurable `shutdown_timeout` in `BigQueryLoggerConfig` to manage how long the plugin waits for pending logs to flush during shutdown.
*   Adds more robust error handling within the `shutdown` method and background write tasks, particularly for event loop closure issues.
*   Improves internal logging to provide better diagnostics.
*   Ensures consistent use of safe content formatting.

PiperOrigin-RevId: 831225837
2025-11-11 22:47:13 -08:00
Shangjie Chen a501c59ac4 feat: Support registering custom services from local files
This change introduces a mechanism for users to register their own custom backend services for sessions, memory, and artifacts without modifying the ADK framework. This enhances the extensibility of ADK.

Two methods of registration are supported, both by placing a file in the parent directory of the agents.

**YAML Configuration (services.yaml or .yml)**

This is the recommended approach for simple services that can be instantiated with a constructor like MyService(uri="...", **kwargs).

Example services.yaml:

```
services:
  - scheme: mysession
    type: session
    class: my_package.my_module.MyCustomSessionService
```

**Python Registration (services.py)**

For services requiring more complex initialization logic, users can define factory functions in a services.py file.

Example services.py

```
from google.adk.cli.service_registry import get_service_registry
from my_package.my_module import MyCustomSessionService

def my_session_factory(uri: str, **kwargs):
    # custom initialization logic
    return MyCustomSessionService(...)

get_service_registry().register_session_service("mysession", my_session_factory)
```

ADK will load services from services.yaml/.yml first, and then from services.py. If the same service scheme is defined in both, the registration in services.py will take precedence.

To use a registered service, specify its URI via the corresponding command-line flag, e.g., `--session_service_uri=mysession://....`

Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 831211371
2025-11-11 21:59:19 -08:00
George Weale 99fc17b336 feat: add adk folder manager and per agent local storage helpers
Creates AdkFolderManager for creating/resetting the .adk layout, helper builders that return SQLite- and filesystembacked services for each agent

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 831206377
2025-11-11 21:38:51 -08:00
Google Team Member 3674fbbe8f fix: Update the retry_on_closed_resource decorator to retry on all errors
Retrying only on closed_resource error is not enough to be reliable for production environments due to the other network errors that may occur -- remote protocol error, read timeout, etc. We will update this to retry on all errors. Since it is only a one-time retry, it should not affect latency significantly. Fixes https://github.com/google/adk-python/issues/2561.

PiperOrigin-RevId: 831153803
2025-11-11 18:44:18 -08:00
Liang Wu 999af55880 chore: Defer import of google.cloud.storage in GCSArtifactService
The `google.cloud.storage` module is now imported within the `__init__` method of `GCSArtifactService`, rather than at the top level. This avoids importing the potentially heavy `storage` module unless an instance of `GCSArtifactService` is actually created.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 831124463
2025-11-11 17:02:20 -08:00
Liang Wu 22ca7eefc0 chore: Defer import of live, Client and _transformers in google.genai
This is targeting the Client import mostly, but also prevents future latency increase if the other modules in genai adds more 3p dependencies. This change will make ADK only import `live`, `Client` and `_transformers` just-in-time, therefore cutting down cold start latency.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 831124329
2025-11-11 17:01:28 -08:00
Kathy Wu a550509441 fix: Update the retry_on_closed_resource decorator to retry on all errors
Retrying only on closed_resource error is not enough to be reliable for production environments due to the other network errors that may occur -- remote protocol error, read timeout, etc. We will update this to retry on all errors. Since it is only a one-time retry, it should not affect latency significantly. Fixes https://github.com/google/adk-python/issues/2561.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 831123085
2025-11-11 16:57:25 -08:00
Google Team Member d85a301039 feat: Add support for passing request metadata in RemoteA2AAgent
This change updates `RemoteA2AAgent` to extract and forward custom metadata from session events to the `a2a-sdk`'s `send_message` method. The metadata is looked for under the key `A2A_METADATA_PREFIX + "metadata"` within the `custom_metadata` of the relevant session events. The `a2a-sdk` dependency is also updated to a version that supports this feature.

This feature was added in v0.3.11 of the a2a-sdk library: https://github.com/a2aproject/a2a-python/releases/tag/v0.3.11

PiperOrigin-RevId: 831120978
2025-11-11 16:49:39 -08:00
Google Team Member 249216e890 feat: Add Graceful Plugin Shutdown to Runner
This change introduces a shutdown lifecycle hook for plugins. The `PluginManager` now has an `async def shutdown()` method that will call `await plugin.shutdown()` on any registered plugins that implement the method. This is called from `Runner.close()`, allowing plugins to perform cleanup tasks like flushing logs or closing connections when the runner instance is being closed. This improves the reliability of plugins that perform background operations.

PiperOrigin-RevId: 831037737
2025-11-11 13:05:03 -08:00
Hangfei Lin 01bac62f0c chore: Update agent instructions and retry limit in plugin_reflect_tool_retry sample
The agent's instructions are updated to guide it to guess a positive integer, starting from 50 and decreasing, using the `guess_number_tool` until the target is found. The maximum number of retries for the `CustomRetryPlugin` is increased from 6 to 10.

Co-authored-by: Hangfei Lin <hangfei@google.com>
PiperOrigin-RevId: 830984481
2025-11-11 10:52:44 -08:00
Hangfei Lin 01a0309f0a chore: Add Go ADK link to README
The README now includes a link to the `adk-go` GitHub repository.

Co-authored-by: Hangfei Lin <hangfei@google.com>
PiperOrigin-RevId: 830971424
2025-11-11 10:21:36 -08:00
Google Team Member 824ab07212 fix: Let part converters also return multiple parts so they can support more usecases
PiperOrigin-RevId: 830882000
2025-11-11 06:15:00 -08:00
Catalin Lupuleti fd33610e96 test: add tests for max_query_result_rows in BigQuery tool config
Merge https://github.com/google/adk-python/pull/2167, during which:

- Let the already added `max_query_result_rows` field cover for `max_downloaded_rows` field added in the PR
- Revert `max_rows` parameter added to execute_sql function, the tool config control should serve most practical use cases
- Keep the relevant tests for tool config

🤖 Generated with [Claude Code](https://claude.ai/code)

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2167 from lupuletic:feature/configurable-max-downloaded-rows 23c56905c297d7aec2be4f1eb86ea23c8178bf21
PiperOrigin-RevId: 830701093
2025-11-10 19:43:24 -08:00
Hangfei Lin 2b0f953255 feat: Add artifact metadata support and a new sample for context offloading
Enhanced `save_artifact` in `callback_context.py` to accept `custom_metadata` and added `get_artifact_version` to retrieve artifact details.

Introduced a new sample, `context_offloading_with_artifact`, demonstrating how to use ADK artifacts to offload large data from the LLM context. The sample includes:
-   `QueryLargeDataTool`: Generates mock sales reports, saves them as artifacts with custom metadata, and injects the artifact content into the LLM request immediately after creation.
-   `CustomLoadArtifactsTool`: Provides summaries of available artifacts to the LLM based on metadata and loads artifact content on demand when `load_artifacts` is called.

Co-authored-by: Hangfei Lin <hangfei@google.com>
PiperOrigin-RevId: 830592786
2025-11-10 14:10:10 -08:00
GitMarco27 74959414d8 feat: full async implementation of DatabaseSessionService
Merge https://github.com/google/adk-python/pull/2889

# Implement Full async DatabaseSessionService

**Target Issue:** #1005

## Overview

This PR introduces an asynchronous implementation of the `DatabaseSessionService` with minimal breaking changes. The primary goal is to enable effective use of ADK in fully async environments and API endpoints while avoiding event loop blocking during database I/O operations.

## Changes

- Converted `DatabaseSessionService` to use async/await patterns throughout

## Testing Plan

The implementation has been tested following the project's contribution guidelines:

### Unit Tests
- All existing unit tests pass successfully
- Minor update to test requirements added to support `aiosqlite`

### Manual End-to-End Testing
- E2E tests performed using:
  - **LLM Provider:** LiteLLM
  - **Database:** PostgreSQL with `asyncpg` driver

 ```python
from google.adk.sessions.database_session_service import DatabaseSessionService

connection_string: str = (
    "postgresql+asyncpg://PG_USER:PG_PSWD@PG_HOST:5432/PG_DB"
)
session_service: DatabaseSessionService = DatabaseSessionService(
    db_url=connection_string
)

session = await session_service.create_session(
    app_name="test_app", session_id="test_session", user_id="test_user"
)
assert session is not None

sessions = await session_service.list_sessions(app_name="test_app", user_id="test_user")
assert len(sessions.sessions) > 0

session = await session_service.get_session(
    app_name="test_app", session_id="test_session", user_id="test_user"
)
assert session is not None

await session_service.delete_session(
    app_name="test_app", session_id="test_session", user_id="test_user"
)
assert (
    await session_service.get_session(
        app_name="test_app", session_id="test_session", user_id="test_user"
    )
    is None
)
```

The implementation have been also tested using the following configurations for llm provider and Runner:

```python
def get_azure_openai_model(deployment_id: str | None = None) -> LiteLlm:
    ...

    if not deployment_id:
        deployment_id = os.getenv("AZURE_OPENAI_DEPLOYMENT_ID")

    logger.info(f"Using Azure OpenAI deployment ID: {deployment_id}")

    return LiteLlm(
        model=f"azure/{os.getenv('AZURE_OPENAI_DEPLOYMENT_ID')}",
        stream=True,
    )

...

    @staticmethod
    def _get_runner(agent: Agent) -> Runner:
        storage=DatabaseSessionService(db_url=get_pg_connection_string())
        return Runner(
            agent=agent,
            app_name=APP_NAME,
            session_service=storage,
        )

...

async for event in self.runner.run_async(
    user_id=user_id,
    session_id=session_id,
    new_message=content,
    run_config=(
        RunConfig(
            streaming_mode=StreamingMode.SSE, response_modalities=["TEXT"]
        )
        if stream
        else RunConfig()
    ),
):
    last_event = event
    if stream:
        yield event

...

```

## Breaking Changes

- Database connection string format may need updates for async drivers

Co-authored-by: Shangjie Chen <deanchen@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2889 from GitMarco27:feature/async_database_session_service e1b1b14934c1fb7975a6832cdd1549e94acab985
PiperOrigin-RevId: 830525148
2025-11-10 11:18:02 -08:00
Shangjie Chen 2443a1b74f docs: Update adk cli help message regarding the update to SqliteSessionService
Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 830521954
2025-11-10 11:09:57 -08:00
George Weale 7b87056dfa fix: adapt fixtures for pytest 9 rules
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 830493430
2025-11-10 10:06:12 -08:00
Amy Wu 7937e9ed40 fix: Use async with for API client in Vertex session management to ensure proper resource management
PiperOrigin-RevId: 830485639
2025-11-10 09:49:10 -08:00
George Weale c4858896ff fix: Update description for load_artifacts tool
The tool description now clarifies that `load_artifacts` should be called when a user uploads files, to make those artifacts accessible within the session.

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 830469802
2025-11-10 09:07:59 -08:00
George Weale 0db2041e1a fix: Correct FastAPI version constraint in toml
The upper bound for the `fastapi` dependency is adjusted from `<1.119.0` to `<0.119.0`.

Close #3422

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 830465681
2025-11-10 08:58:15 -08:00
Jeff Bryner 352dd995e1 fix: Add required parameters with defaults if missing
Merge https://github.com/google/adk-python/pull/2054

fixes https://github.com/google/adk-python/issues/2053

Co-authored-by: Xuan Yang <xygoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2054 from jeffbryner:fix-required-params dd75a0b5798792dccb1ca0ac0240ce0c0b1fad14
PiperOrigin-RevId: 830251203
2025-11-09 20:46:41 -08:00
Xuan Yang f31226ee92 docs: Update the error message for function parameter ToolContext not named as tool_context
Fixes https://github.com/google/adk-python/issues/1530

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 830248414
2025-11-09 20:35:28 -08:00
George Weale 93aad61198 fix: Safely handle FunctionDeclaration without a required attribute
Update `_function_declaration_to_tool_param` to use `getattr` when accessing the `required` field within `function_declaration.parameters`. This prevents `AttributeError` when a `FunctionDeclaration`'s parameters schema does not include a `required` attribute
Close #2891

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 830225582
2025-11-09 19:06:45 -08:00
Sanjay Siddharth MJ 2882995289 fix: Fixes DeprecationWarning when using send method
Merge https://github.com/google/adk-python/pull/3352

Replace send() method with send_realtime_input() to fix DeprecationWarning

### Link to Issue or Description of Change

**1. Link to an existing issue (if applicable):**

- Closes: #2393

### Testing Plan

Have run unit test for test_live_request_queue.py

**Unit Tests:**

- [ ] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

Summary :

tests/unittests/agents/test_live_request_queue.py::test_send_realtime PASSED                [100%]

**Manual End-to-End (E2E) Tests:**

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] 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.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [ ] Any dependent changes have been merged and published in downstream modules.

Tested both API variants.

Co-authored-by: Hangfei Lin <hangfei@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3352 from SanjaySiddharth:fix-dep-session.send b23b641a63ff20d1f2dbd9abd519f8facf0aab77
PiperOrigin-RevId: 830182844
2025-11-09 16:00:43 -08:00
GenkiNoguchi a3b4ec69d8 feat: Add user_id property to ReadonlyContext
Merge https://github.com/google/adk-python/pull/2875

related: https://github.com/google/adk-python/issues/2876

  ## Reason for this change:

  Currently, there is no direct way to access the user_id from within agent contexts, plugins, or callbacks. This limitation prevents several important use cases:

  1. **User-specific logging and tracing**: When debugging or monitoring agent behavior, it's crucial to associate actions with specific users for better observability.
  2. **User-scoped operations**: Plugins and callbacks often need to perform user-specific operations, such as accessing user-specific resources or applying user-level configurations.
  3. **Session management**: The user_id is a key component of session identification, but it's not accessible through the ReadonlyContext interface, requiring workarounds to access it.

  ## Changes made:

  - Added a `user_id` property to the `ReadonlyContext` class in `src/google/adk/agents/readonly_context.py`
  - The property exposes the user_id from the underlying invocation context as a readonly field

  ## Impact:

  This change will:
  - Enable plugins and callbacks to access the current user's ID directly through the context
  - Improve logging and tracing capabilities by allowing user-specific tracking
  - Simplify code that needs to perform user-scoped operations without requiring access to internal implementation details
  - Maintain backward compatibility as this is an additive change

  ### Before:
- No direct way to access user_id from ReadonlyContext

###   After:
  ```python

  @property
  def user_id(self) -> str:
      """The id of the user. READONLY field."""
      return self._invocation_context.user_id
```
  This is a non-breaking change that adds a new readonly property to the existing ReadonlyContext interface.

Co-authored-by: Hangfei Lin <hangfei@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2875 from ammmr:ammmr-add-user_id-property-to-readonly-context 771734ebf39cb0748a5dc826436236268fbb58f8
PiperOrigin-RevId: 830170908
2025-11-09 14:51:52 -08:00
Max Ind 116b26c33e feat: add plugin for returning GenAI Parts from tools into the model request
Added to mitigate https://github.com/google/adk-python/issues/3064

Co-authored-by: Max Ind <maxind@google.com>
PiperOrigin-RevId: 830135940
2025-11-09 11:47:08 -08:00
Shangjie Chen e218254495 feat: Add SqliteSessionService and a migration script to migrate existing DB using DatabaseSessionService to SqliteSessionService
The new Sqlite version has fixed schema and use a single column to store Event data, this should avoid DB migration for future add to the Event object.

- This change introduces `SqliteSessionService`, an asynchronous session service using `aiosqlite` that stores event data as JSON within SQLite.
- A migration script, `migrate_from_sqlalchemy_sqlite.py`, is included to transition data from the older SQLAlchemy-based SQLite schema to this new format.
- The CLI service registry is updated to use SqliteSessionService for sqlite:// URIs.
- Throw error when user trying to access a legacy DB and advice the user to do the migration.

Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 829971174
2025-11-08 21:19:38 -08:00
Wei Sun (Jack) 50ceda00cf docs(models): Updates BaseLlm#generate_content_async docstring with the expected behavior
NOTE:

- This is the expected behavior, so that SSE streaming and non-streaming behaviors are idential to each other in the persisted session.
- The underlying google_llm.py hasn't been fully comply with this behavior, which will be addressed in future changes.

Co-authored-by: Wei Sun (Jack) <weisun@google.com>
PiperOrigin-RevId: 829878175
2025-11-08 13:21:38 -08:00
Google Team Member 6b14f88726 feat: Refactor and Rename BigQuery Agent Analytics Plugin
This change updates the `BigQueryAgentAnalyticsPlugin` (formerly in `bigquery_logging_plugin.py`) to perform BigQuery writes asynchronously in background tasks, preventing blocking of the main agent execution flow. Initialization of BigQuery clients and table creation is also made asynchronous. The content logged in various callbacks has been streamlined and simplified. The plugin file has been renamed to `bigquery_agent_analytics_plugin.py` to match the class name.

PiperOrigin-RevId: 829603260
2025-11-07 15:44:03 -08:00
GenkiNoguchi 42d4c4ed5f chore: Change live connection log level from info to debug
Merge https://github.com/google/adk-python/pull/2600

**Reason for this change:**

Currently, the detailed llm_request object is logged at the info level when connecting to the live API. This causes two main issues:

  1. Excessive log output with large instructions: When instructions are large, the unstructured log output becomes problematic. Since the logs are not structured, any
  newline characters in the instruction content cause each line to be output as a separate log entry, resulting in massive log output that floods the logging system.
  2. Unnecessary verbosity in production: The detailed request information is primarily useful for debugging purposes and should not appear in standard info-level logs,
  especially when connections are established frequently.

  **Changes made:**

  - Changed logger.info to logger.debug in src/google/adk/models/google_llm.py at line 294 for the live connection logging statement.

  **Impact:**

  This change will:
  - Reduce log noise in production environments where info-level logging is enabled
  - Keep the detailed connection information available when debug-level logging is needed for troubleshooting
  - Improve log readability by showing only essential information at the info level

  **Before:**
  logger.info('Connecting to live with llm_request:%s', llm_request)

  **After:**
  logger.debug('Connecting to live with llm_request:%s', llm_request)

  This is a non-breaking change that only affects logging verbosity.

Co-authored-by: Hangfei Lin <hangfei@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2600 from ammmr:ammmr-info-to-debug-connect-log 36eab157f5d5ca00b44ee6ad8a4e1aeec871600c
PiperOrigin-RevId: 829596092
2025-11-07 15:20:10 -08:00
Google Team Member 34ea2edfd2 fix: Fixes a bug introduced by the underlying google genai library
We need to set project and location parameters when we instantiate the Google GenAI library Client for VertexAi. This used to work before through environment variables but it doesn't seem to work anymore. So we are updating the `ApigeeLlm` wrapper to read from `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION` environment variables and pass to the Client constructor.

PiperOrigin-RevId: 829569362
2025-11-07 14:02:41 -08:00
Google Team Member 9e22cc4022 feat: Bigquery detect_anomalies tool results sort by timestamp for better visualization
Timestamp need to be ordered so that for better display and further visualization.

PiperOrigin-RevId: 829548481
2025-11-07 13:03:34 -08:00
Lê Nam Khánh 51dee43f08 docs: fix typos in some files
Merge https://github.com/google/adk-python/pull/3444

This PR fixes typos in the file file using codespell.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3444 from khanhkhanhlele:Fix/typos/20251107165249 e9629a8c0255ddc0764cb0df7f36ebe61bd6515e
PiperOrigin-RevId: 829516217
2025-11-07 11:32:32 -08:00
George Weale e0e762598e docs: Use a trimmed ADK AgentConfig schema in Agent Builder Assistant
This trimmed schema includes only the fields relevant to agent shells, tool wiring, and common generation parameters, improving efficiency and focus.

The default model for the assistant has also been updated to "gemini-2.5-pro"

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 829513627
2025-11-07 11:26:18 -08:00
Henrique Cadioli 8f3c3bfda5 fix: cache canonical tools to avoid multiple calls when streaming
Merge https://github.com/google/adk-python/pull/3299
Fixes https://github.com/google/adk-python/issues/3237

Co-authored-by: Xuan Yang <xygoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3299 from hcadioli:fix/cache-tools de02bd3e4533c3741edf05788a5e8b2d3d38bae4
PiperOrigin-RevId: 829499299
2025-11-07 10:51:32 -08:00
Kathy Wu 9761fc6bbb fix: Fix McpToolset hanging indefinitely
This fixes McpToolset from hanging indefinitely during a list_tools call (https://github.com/google/adk-python/issues/3084) by adding a timeout.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 829499276
2025-11-07 10:50:38 -08:00
Naofumi Yamada 0ccc43cf49 fix: Fix error when query job destination is None
Merge https://github.com/google/adk-python/pull/3127

# What this PR does
This PR fixes a bug in the `execute_sql function` within `bigquery/query_tool.py`. The bug caused an error when executing queries that do not return a result set, such as a `CREATE TEMP FUNCTION` statement.

# The problem
Within `execute_sql,` when a user executed a query that doesn't produce a result set, like the following:

```sql
CREATE TEMP FUNCTION f() AS (0); SELECT f();
```

The corresponding BigQuery job object would have its `destination` property set to `None`. This caused an error because the code was written with the expectation of a valid destination table.

# The solution
The fix modifies `execute_sql` to check if the `query_job.destination` is None. If it is, the function correctly identifies the query as a statement that doesn't require a destination and allows it to complete successfully.

This ensures that `execute_sql` can robustly handle these types of queries.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3127 from na0fu3y:patch-1 69218a8d25699dfa2e18bb305087f01192e91e91
PiperOrigin-RevId: 829270885
2025-11-06 22:28:06 -08:00
Google Team Member a0cf97eba2 feat: Some small infra fixes to the gepa demo colab
PiperOrigin-RevId: 829240716
2025-11-06 20:44:25 -08:00
Google Team Member d118479ccf feat: Improve gepa voter agent demo colab
PiperOrigin-RevId: 829208761
2025-11-06 19:13:11 -08:00
Kathy Wu 8e0648df23 fix: Fix MCPToolset crashing with anyio.BrokenResourceError
Add error handling for broken resource error so that it retries. Fixes https://github.com/google/adk-python/issues/2769.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 829146121
2025-11-06 16:12:49 -08:00
Google Team Member c0be1df052 feat: set per-tool user agent in BQ calls and tool label in BQ jobs
This will help per tool usage for BigQuery tools.

PiperOrigin-RevId: 829142106
2025-11-06 16:01:50 -08:00
Google Team Member f1f44675e4 ADK changes
PiperOrigin-RevId: 829136628
2025-11-06 15:55:26 -08:00
Hangfei Lin f3d6fcf444 chore: Add debug logging for missing function call events
This change adds a debug log statement to output the function response IDs and the event list when a matching function call event is not found, which helps in debugging.

Co-authored-by: Hangfei Lin <hangfei@google.com>
PiperOrigin-RevId: 829059186
2025-11-06 12:20:36 -08:00
Liang Wu dd706bdc45 feat: Update conformance test CLI to handle long-running tool calls
Capture the function call ID from events and use it to populate the `function_response.id` in subsequent user messages, enabling recording and replaying of test cases involving long-running tools.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 829042356
2025-11-06 11:38:13 -08:00
Wei Sun (Jack) e511eb1f70 chore: Removes the unrealistic todo comment of visibility management
Co-authored-by: Wei Sun (Jack) <weisun@google.com>
PiperOrigin-RevId: 829041637
2025-11-06 11:36:49 -08:00
George Weale 7ea4aed35b fix: Add support for structured output schemas in LiteLLM models
Add `_to_litellm_response_format` to convert ADK's `response_schema` types (Pydantic models, JSON schema dicts) into the format needed by LiteLLM for JSON object/schema constraints

Close #1967

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 829037987
2025-11-06 11:29:10 -08:00
Josh Soref d672349ddf chore: Fix spelling in tests
Merge https://github.com/google/adk-python/pull/3402

This PR corrects misspellings identified by the [check-spelling action](https://github.com/marketplace/actions/check-spelling)

Note: while I use tooling to identify errors, the tooling doesn't _actually_ provide the corrections, I'm picking them on my own. I'm a human, and I may make mistakes.

### Testing Plan

The misspellings have been reported at https://github.com/jsoref/adk-python/actions/runs/19056081305/attempts/1#summary-54426435973

The action reports that the changes in this PR would make it happy: https://github.com/jsoref/adk-python/actions/runs/19056081446/attempts/1#summary-54426436321

**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

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] 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

- https://github.com/google/adk-python/pull/3382#issuecomment-3488654110

Co-authored-by: Liang Wu <wuliang@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3402 from jsoref:spelling-tests 3cf0439d0584e4557179c25596aadf3b5b7c3fa8
PiperOrigin-RevId: 829035089
2025-11-06 11:21:59 -08:00
Hangfei Lin 1819ecb4b8 fix: Improve handling of partial and complete transcriptions in live calls
In `gemini_llm_connection.py`, accumulate partial transcription texts and emit `LlmResponse` with `partial=True` for each chunk. When the transcription is marked as `finished`, emit a final `LlmResponse` with the full accumulated text and `partial=False`.

In `runners.py`, modify `_should_append_to_history` to only add transcription events to the history when they are fully finished, preventing partial transcriptions from being added.

Co-authored-by: Hangfei Lin <hangfei@google.com>
PiperOrigin-RevId: 829029715
2025-11-06 11:09:21 -08:00
Liang Wu 44d45fe9cd chore: Lazy load Vertex AI dependencies in ADK modules
This is about 35% decrease. This change refactors several ADK modules to import `vertexai` and its submodules only when they are first used, rather than at the top of the file. This improves module load times by avoiding unnecessary imports of large dependencies. Imports are also placed within `if TYPE_CHECKING:` blocks where appropriate.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 829017293
2025-11-06 10:40:54 -08:00
Liang Wu 5f057498a2 chore: Lazy import DatabaseSessionService in the adk/sessions/ module
This accounts for about 8% of latency in cold start, because DatabaseSessionService imports from sqlalchemy. After the change, DatabaseSessionService is only imported if it's really needed by the program. The other objects in this file are not affected because they contribute to a small fraction of the latency.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 829009868
2025-11-06 10:24:43 -08:00
Krzysztof Czuszynski 8dd5a79b29 fix: Fix transcript finish
Merge https://github.com/google/adk-python/pull/3324

**Problem:**
ADK seems to not pass output/input transcription `finished` flag from the Gemini.

**Solution:**
Relaxation of checking conditions of valid llm_response for input/output transcription.

### Testing Plan

Unit test `test_receive_transcript_finished` checks if input/output transcription message with no text but `finished` flag is received.

**Unit Tests:**

- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

<img width="785" height="373" alt="image" src="https://github.com/user-attachments/assets/6d870e9f-1372-4808-91a9-38578c1b3729" />

**Manual End-to-End (E2E) Tests:**

Configure Gemini Agent to produce input & output transcriptions. Observe incoming transcript messages - to see if the finished flag appears at the end agents & users statement.

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.

### Additional context

The mentioned `finished` flag can be obtained in native Gemini APIs like via Websocket but not via ADK.

Co-authored-by: Hangfei Lin <hangfei@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3324 from ChrisQlasty:fix/transcript_finish e7b8e5e5f5fac1d2dfd495f2dbadb19ed4328b0c
PiperOrigin-RevId: 828987996
2025-11-06 09:29:12 -08:00
Google Team Member f167890d00 feat: Add documentation and instructions to help configure gepa experiments
PiperOrigin-RevId: 828911323
2025-11-06 05:31:24 -08:00
George Weale e3caf79139 feat: expose artifact URLs to the model when available
SaveFilesAsArtifactsPlugin now resolves the canonical URI for each saved artifact. When the URI is model-accessible (`gs://`, `https://`, `http://`), we add a `Part(file_data=...)` so the LLM can fetch the filedirectly while still emitting the placeholder. If no model-accessible URI exists, we retain the original inline blob alongside the placeholder to preserve access to the uploaded bytes.

Close #2016

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 828786519
2025-11-05 22:17:37 -08:00
Hangfei Lin 52db15f133 fix: Remove unused _run_compaction_default method
The `_run_compaction_default` method is no longer called and can be safely removed.

Co-authored-by: Hangfei Lin <hangfei@google.com>
PiperOrigin-RevId: 828760157
2025-11-05 20:47:09 -08:00
Josh Soref e568558674 chore: Fix spelling in markdown files
Merge https://github.com/google/adk-python/pull/3403

This PR corrects misspellings identified by the [check-spelling action](https://github.com/marketplace/actions/check-spelling)

Note: while I use tooling to identify errors, the tooling doesn't _actually_ provide the corrections, I'm picking them on my own. I'm a human, and I may make mistakes.

### Testing Plan

The misspellings have been reported at https://github.com/jsoref/adk-python/actions/runs/19056081305/attempts/1#summary-54426435973

The action reports that the changes in this PR would make it happy: https://github.com/jsoref/adk-python/actions/runs/19056081446/attempts/1#summary-54426436321

**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

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] 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

- https://github.com/google/adk-python/pull/3382#issuecomment-3488654110

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3403 from jsoref:spelling-markdown 432b7ded3bddfe4a1d8127c50fd7a001f19bda83
PiperOrigin-RevId: 828754459
2025-11-05 20:30:49 -08:00
Kapil Sachdeva d7521eb638 feat: Expose run_config of current invocation from ReadonlyContext
Merge https://github.com/google/adk-python/pull/3410

### Link to Issue or Description of Change

**1. Link to an existing issue (if applicable):**

- Closes: #3409

Co-authored-by: Hangfei Lin <hangfei@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3410 from ksachdeva:expose-runconfig b62b923df421f0bdc1c20948d16765c555c01cb8
PiperOrigin-RevId: 828738445
2025-11-05 19:47:11 -08:00
Shangjie Chen f511352508 chore: Clarify the usage of agent_state
Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 828733706
2025-11-05 19:30:58 -08:00
ananyablonko 0fccc7933a fix(core): ParallelAgent's branching with include_contents='none' may cause index out of range error
Merge https://github.com/google/adk-python/pull/2961

Fixes #2404

Consider code where a sub_agent somewhere under a ParallelAgent has include_contents='none'.
```python
import asyncio
import os
from typing import TypedDict
from dotenv import load_dotenv

from google.adk.agents import LlmAgent, ParallelAgent, SequentialAgent
from google.adk.runners import Runner
from google.adk.sessions import DatabaseSessionService, InMemorySessionService
from google.genai import types
import logging

USE_DB=False

load_dotenv()
logging.basicConfig(
    filename='log.log',
    level=logging.DEBUG
)
for logger_name in ["httpcore"]:
    logging.getLogger(logger_name).setLevel(logging.ERROR)

class AgentArgs(TypedDict):
    model: str
    instruction: str

class SessionArgs(TypedDict):
    user_id: str
    session_id: str

agent_args = AgentArgs(
    model="gemini-2.0-flash",
    instruction="Answer 'Ack' and nothing else."
)

session_args = SessionArgs(
    user_id="0",
    session_id="0"
)

app_name = "Test"

def create_agent_in_branch(i: int):
    agent_1 = LlmAgent(
        name=f"subagent_{i}_1",
        **agent_args
    )

    agent_2 = LlmAgent(
        name=f"subagent_{i}_2",
        include_contents='none',
        **agent_args
    )

    return SequentialAgent(
        name=f"agent_{i}",
        sub_agents=[agent_1, agent_2]
    )

root = ParallelAgent(
    name="root",
    sub_agents=[create_agent_in_branch(i) for i in range(1, 5)]
)

runner = Runner(
    agent=root,
    app_name=app_name,
    session_service=DatabaseSessionService(db_url=os.getenv("DB_URL", "")) if USE_DB else InMemorySessionService(),
)

async def main() -> None:
    try:
        await runner.session_service.delete_session(app_name=app_name, **session_args)
    except:
        pass
    await runner.session_service.create_session(app_name=app_name, **session_args)

    message = types.Content(role="user", parts=[types.Part(text=" ")])
    async for event in runner.run_async(**session_args, new_message=message):
        if event.is_final_response():
            print(((event.content or types.Content()).parts or [types.Part()])[0].text or "")

if __name__ == '__main__':
    asyncio.run(main())
```

The log here will often have one or more ```subagent_{i}_2``` not receive their prompts from ```subagent_{i}_1```.
This inconsistency is caused by the way ```include_contents='none'``` is implemented in flows/llm_flows/contents.py:328-356:

```python
    for i in range(len(events) - 1, -1, -1):
    event = events[i]
    if event.author == 'user' or _is_other_agent_reply(agent_name, event):
      return _get_contents(current_branch, events[i:], agent_name)

  return []
```

That is, we first find the most recent (other-agent / user) event, **even if it's not on our branch**, and then filter the remainder. Thus in the above example, we may sometimes filter out all events, when we expect to have the event of a previous agent in a ```SequentialAgent```.

The solution is to first filter events by branch, and only then search for the latest.

### TEST SUMMARY:
```
=================================================== short test summary info ===================================================
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[GOOGLE_AI-LoopAgent-LoopAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[GOOGLE_AI-google.adk.agents.LoopAgent-LoopAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[GOOGLE_AI-google.adk.agents.loop_agent.LoopAgent-LoopAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[GOOGLE_AI-ParallelAgent-ParallelAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[GOOGLE_AI-google.adk.agents.ParallelAgent-ParallelAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[GOOGLE_AI-google.adk.agents.parallel_agent.ParallelAgent-ParallelAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[GOOGLE_AI-SequentialAgent-SequentialAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[GOOGLE_AI-google.adk.agents.SequentialAgent-SequentialAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[GOOGLE_AI-google.adk.agents.sequential_agent.SequentialAgent-SequentialAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[VERTEX-LoopAgent-LoopAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[VERTEX-google.adk.agents.LoopAgent-LoopAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[VERTEX-google.adk.agents.loop_agent.LoopAgent-LoopAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[VERTEX-ParallelAgent-ParallelAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[VERTEX-google.adk.agents.ParallelAgent-ParallelAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[VERTEX-google.adk.agents.parallel_agent.ParallelAgent-ParallelAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[VERTEX-SequentialAgent-SequentialAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[VERTEX-google.adk.agents.SequentialAgent-SequentialAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_with_sub_agents[VERTEX-google.adk.agents.sequential_agent.SequentialAgent-SequentialAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_llm_agent_with_sub_agents[GOOGLE_AI-LlmAgent-LlmAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_llm_agent_with_sub_agents[GOOGLE_AI-google.adk.agents.LlmAgent-LlmAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_llm_agent_with_sub_agents[GOOGLE_AI-google.adk.agents.llm_agent.LlmAgent-LlmAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_llm_agent_with_sub_agents[VERTEX-LlmAgent-LlmAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_llm_agent_with_sub_agents[VERTEX-google.adk.agents.LlmAgent-LlmAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/agents/test_agent_config.py::test_agent_config_discriminator_llm_agent_with_sub_agents[VERTEX-google.adk.agents.llm_agent.LlmAgent-LlmAgent] - FileNotFoundError: Config file not found: C:\Users\AnanYablonko\AppData\Local\Temp\pytest-of-AnanYablonko\pytest-1\test_age...
FAILED tests/unittests/cli/utils/test_cli_tools_click.py::test_cli_run_invokes_run_cli[GOOGLE_AI] - AssertionError: assert 1 == 0
FAILED tests/unittests/cli/utils/test_cli_tools_click.py::test_cli_run_invokes_run_cli[VERTEX] - AssertionError: assert 1 == 0
FAILED tests/unittests/cli/utils/test_cli_tools_click.py::test_cli_eval_with_eval_set_file_path[GOOGLE_AI] - assert 0 == 1
FAILED tests/unittests/cli/utils/test_cli_tools_click.py::test_cli_eval_with_eval_set_file_path[VERTEX] - assert 0 == 1
FAILED tests/unittests/evaluation/test_local_eval_sets_manager.py::TestLocalEvalSetsManager::test_local_eval_sets_manager_update_eval_case_eval_set_not_found[GOOGLE_AI] - OSError: [Errno 22] Invalid argument: '<tests.unittests.evaluation.test_local_eval_sets_manager.TestLocalEvalSetsManager ob...
FAILED tests/unittests/evaluation/test_local_eval_sets_manager.py::TestLocalEvalSetsManager::test_local_eval_sets_manager_update_eval_case_eval_set_not_found[VERTEX] - OSError: [Errno 22] Invalid argument: '<tests.unittests.evaluation.test_local_eval_sets_manager.TestLocalEvalSetsManager ob...
FAILED tests/unittests/evaluation/test_local_eval_sets_manager.py::TestLocalEvalSetsManager::test_local_eval_sets_manager_delete_eval_case_eval_set_not_found[GOOGLE_AI] - OSError: [Errno 22] Invalid argument: '<tests.unittests.evaluation.test_local_eval_sets_manager.TestLocalEvalSetsManager ob...
FAILED tests/unittests/evaluation/test_local_eval_sets_manager.py::TestLocalEvalSetsManager::test_local_eval_sets_manager_delete_eval_case_eval_set_not_found[VERTEX] - OSError: [Errno 22] Invalid argument: '<tests.unittests.evaluation.test_local_eval_sets_manager.TestLocalEvalSetsManager ob...
FAILED tests/unittests/sessions/test_session_service.py::test_get_session_with_config[GOOGLE_AI-SessionServiceType.DATABASE] - OSError: [Errno 22] Invalid argument
FAILED tests/unittests/sessions/test_session_service.py::test_get_session_with_config[VERTEX-SessionServiceType.DATABASE] - OSError: [Errno 22] Invalid argument
================================= 34 failed, 4540 passed, 3044 warnings in 187.68s (0:03:07) ==================================
```

Co-authored-by: Wei Sun (Jack) <weisun@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2961 from ananyablonko:main b4a21adcd4231efeffd552a96734b2161b317e0a
PiperOrigin-RevId: 828700099
2025-11-05 17:41:35 -08:00
Lorenzo 63b69fbc0f fix(cli): Handle the case when OS doesn't support symlink for adk run
Merge https://github.com/google/adk-python/pull/2582

Relate to #3306

## Description
Fixes issues #6 and #1785 where ADK commands crash on Windows due to symlink creation requiring admin privileges.

## Problem
On Windows, running ADK commands (like `adk run`) fails with `OSError: [WinError 1314] A required privilege is not held by the client: ...` because the logging system attempts to create a symlink for the latest log file. Windows requires administrator privileges for symlink creation by default (unless Developer Mode is enabled), causing crashes for non-admin users.

## Root Cause
The issue was in [`logs.py`](https://github.com/google/adk-python/blob/main/src/google/adk/cli/utils/logs.py#L72) where `os.symlink()` was called unconditionally without error handling, causing the entire CLI to crash when symlink creation failed.

## Solution
This PR implements graceful symlink handling. Changes made:
- Extracted symlink creation into separate function with error handling
- Added graceful fallback when symlink creation fails
- Replaced crashes with warnings to keep CLI functional
- Improved user messaging about log file locations

This solution follows a similar pattern to the one used in [ROS2](https://github.com/ros2) in its [logging module](https://github.com/ros2/launch/blob/rolling/launch/launch/logging/__init__.py#L93).

## Testing
### Before (broken)
```bash
> adk run my_agent
Log setup complete: C:\Users\username\AppData\Local\Temp\agents_log\agent.20250817_215119.log
Traceback (most recent call last):
  File "google\adk\cli\utils\logs.py", line 72, in log_to_tmp_folder
    os.symlink(log_filepath, latest_log_link)
OSError: [WinError 1314] A required privilege is not held by the client
```

### After (fixed)
```bash
> adk run my_agent
Log setup complete: C:\Users\username\AppData\Local\Temp\agents_log\agent.20250817_215319.log
UserWarning: Cannot create symlink for latest log file: [WinError 1314] A required privilege is not held by the client
To access latest log: tail -F C:\Users\username\AppData\Local\Temp\agents_log\agent.20250817_215319.log
Running agent my_agent, type exit to exit.
```

Co-authored-by: Wei Sun (Jack) <weisun@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2582 from lorenzofavaro:fix/windows-symlink-permissions 1e99a6287994f1bfd9ac11550d3dc06205998df5
PiperOrigin-RevId: 828690483
2025-11-05 17:09:51 -08:00
Josh Soref 1d80d32efc chore: Fix spelling in src
Merge https://github.com/google/adk-python/pull/3382

This PR corrects misspellings identified by the [check-spelling action](https://github.com/marketplace/actions/check-spelling)

Note: while I use tooling to identify errors, the tooling doesn't _actually_ provide the corrections, I'm picking them on my own. I'm a human, and I may make mistakes.

### Testing Plan

The misspellings have been reported at https://github.com/jsoref/adk-python/actions/runs/19056081305/attempts/1#summary-54426435973

The action reports that the changes in this PR would make it happy: https://github.com/jsoref/adk-python/actions/runs/19056081446/attempts/1#summary-54426436321

**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

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] 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

- follow-up to #2447

Co-authored-by: Hangfei Lin <hangfei@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3382 from jsoref:spelling 3df5932e97391c437e1638d7163e5e3d5c52d5c3
PiperOrigin-RevId: 828686941
2025-11-05 16:59:10 -08:00
Google Team Member 48681cb31b chore: Returns agent state regardless if ctx.is_resumable
This allows state to be passing across agents

PiperOrigin-RevId: 828665491
2025-11-05 15:59:57 -08:00
Josh Soref 59d422ca21 chore: Fix spelling in contributing
Merge https://github.com/google/adk-python/pull/3394

This PR corrects misspellings identified by the [check-spelling action](https://github.com/marketplace/actions/check-spelling)

Note: while I use tooling to identify errors, the tooling doesn't _actually_ provide the corrections, I'm picking them on my own. I'm a human, and I may make mistakes.

### Testing Plan

The misspellings have been reported at https://github.com/jsoref/adk-python/actions/runs/19056081305/attempts/1#summary-54426435973

The action reports that the changes in this PR would make it happy: https://github.com/jsoref/adk-python/actions/runs/19056081446/attempts/1#summary-54426436321

**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

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] 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

- https://github.com/google/adk-python/pull/3382#issuecomment-3488654110

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3394 from jsoref:spelling-contributing c3d5e342c4350f7cae9f8f0c6638b176f2e30e80
PiperOrigin-RevId: 828659867
2025-11-05 15:43:25 -08:00
Google Team Member a2ce34a0b9 feat: Migrate BigQuery logging to Storage Write API
This commit refactors the `BigQueryAgentAnalyticsPlugin` to leverage the modern BigQuery Storage Write API, replacing the previous implementation that used the legacy `insert_rows_json` method (based on `tabledata.insertAll`).

**Key Changes:**

*   **Switched to Storage Write API:** Event logs are now ingested using the `BigQueryWriteClient` from the `google-cloud-bigquery-storage` library.
*   **Utilizes Default Stream:** We are using the `_default` stream for sending data, which is an efficient method for streaming in data without needing to manage stream lifecycles. This is ideal for continuous event logging.
*   **Apache Arrow Format:** Log entries are converted to the Apache Arrow format using `pyarrow` before being sent. The BigQuery table schema is dynamically converted to an Arrow schema. This binary format is more efficient than JSON.
*   **Updated Initialization:** The plugin now initializes both the standard `bigquery.Client` (for table management) and the `BigQueryWriteClient`.
*   **Test Updates:** Unit tests in `test_bigquery_logging_plugin.py` have been comprehensively updated to mock the new `BigQueryWriteClient`, `bq_schema_utils`, and `pyarrow` components. Tests now verify calls to `append_rows` and the data structure passed to create the Arrow RecordBatch.

**Benefits of this change:**

*   **Improved Performance:** The Storage Write API is designed for high-throughput streaming and offers better performance compared to the legacy API.
*   **Reduced Cost:** Ingesting data via the Storage Write API is generally more cost-effective.
*   **Enhanced Reliability:** The Storage Write API provides more robust streaming capabilities.
*   **Modernization:** Aligns the plugin with the recommended best practices for BigQuery data ingestion.

This change enhances the efficiency and scalability of the BigQuery logging plugin.

PiperOrigin-RevId: 828655496
2025-11-05 15:33:57 -08:00
Wei Sun (Jack) fa5c546a55 fix(tools): Add proper cleanup for AgentTool to prevent MCP session errors
Merge https://github.com/google/adk-python/pull/3411

## Summary

Fixes AgentTool cleanup to prevent MCP session errors by calling `runner.close()` after sub-agent execution.

## Problem

When using AgentTool with MCP tools, the runner cleanup happened during garbage collection in a different async task context, causing:
```
RuntimeError: Attempted to exit cancel scope in a different task than it was entered in
```

## Solution

- Call `await runner.close()` immediately after sub-agent execution in AgentTool
- This ensures MCP sessions and other resources are cleaned up in the correct async task context
- Updated test mock to include the close() method

## Demo Agents

Added two comprehensive demo agents showing how to use AgentTool with MCP tools:

### mcp_in_agent_tool_remote (SSE mode)
- Uses HTTP/SSE connection to remote MCP server
- Zero-installation setup with `uvx`
- Demonstrates server-side MCP deployment pattern

### mcp_in_agent_tool_stdio (stdio mode)
- Uses subprocess connection with automatic server launch
- Fully automatic setup with `uvx` subdirectory syntax
- Demonstrates embedded MCP deployment pattern

Both demos:
- Use Gemini 2.5 Flash
- Include example prompts for JSON Schema exploration
- Have comprehensive READMEs with architecture diagrams
- Follow ADK agent structure conventions

## Testing

-  All existing unit tests pass
-  Manual testing with both SSE and stdio modes
-  Verified cleanup happens in correct async context
-  No more cancel scope errors with MCP tools

## Related

- Fixes #1112
- Related to #929

Co-authored-by: Wei Sun (Jack) <weisun@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3411 from google:fix/agent-tool-mcp-cleanup 9ae753b5a4
PiperOrigin-RevId: 828651896
2025-11-05 15:23:39 -08:00
Kathy Wu ee8106be77 fix: Fix error handling when MCP server is unreachable
Currently ADK web hangs and logs "AGSI callable returned without completing response" when the server is unreachable. To fix, set timeouts for connecting to server.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 828648928
2025-11-05 15:15:58 -08:00
George Weale 99ca6aa6e6 feat: add file-backed artifact service
- add FileArtifactService that persists artifacts to the local filesystem
- adjust BaseArtifactService and exports so callers can wire in the filebacked implementation

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 828629298
2025-11-05 14:26:51 -08:00
George Weale d9ec07d39b docs: Improve Agent Builder Assistant schema reference for prompts
Replace the full JSON schema dump with a compact text summary of key AgentConfig components like LlmAgent, ToolConfig, and GenerateContentConfig

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 828627911
2025-11-05 14:23:18 -08:00
Josh Soref 2b31bd9414 chore: Fix spelling: provide
Merge https://github.com/google/adk-python/pull/3407

This PR corrects misspellings identified by the [check-spelling action](https://github.com/marketplace/actions/check-spelling)

Note: while I use tooling to identify errors, the tooling doesn't _actually_ provide the corrections, I'm picking them on my own. I'm a human, and I may make mistakes.

### Testing Plan

The misspellings have been reported at https://github.com/jsoref/adk-python/actions/runs/19056081305/attempts/1#summary-54426435973

The action reports that the changes in this PR would make it happy: https://github.com/jsoref/adk-python/actions/runs/19056081446/attempts/1#summary-54426436321

**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

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] 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

- https://github.com/google/adk-python/pull/3382#issuecomment-3488654110

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3407 from jsoref:spelling-issue-template ce8febc6ab5368640c0ec2ae5d6a2c8ac5bf8ed6
PiperOrigin-RevId: 828610865
2025-11-05 13:40:17 -08:00
Google Team Member e02f177790 feat: Improve gepa tau-bench colab for external use
PiperOrigin-RevId: 828579343
2025-11-05 12:23:47 -08:00
Xuan Yang 9ec38c0d89 feat: Add on_model_error_callback in LlmAgent
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 828560608
2025-11-05 11:37:08 -08:00
Shangjie Chen d6b928bdf7 chore: Returns agent state regardless if ctx.is_resumable
This allows state to be passing across agents

Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 828557989
2025-11-05 11:31:26 -08:00
Google Team Member 744f94f0c8 fix: Add None check for event in remote_a2a_agent.py
PiperOrigin-RevId: 828538350
2025-11-05 10:47:24 -08:00
Xuan Yang d8d7774f0f chore: Update v1.18.0 wheel and CHANGELOG.md
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 828533243
2025-11-05 10:35:33 -08:00
Hangfei Lin 082675546f chore: Stop logging the full content of LLM blobs
The blob content is often large and binary, which makes the logs unreadable and can cause excessive logging.

Co-authored-by: Hangfei Lin <hangfei@google.com>
PiperOrigin-RevId: 828523413
2025-11-05 10:12:07 -08:00
Hangfei Lin aa77834e2e chore: Update Gemini Live model names in live bidi streaming sample
The sample agent now uses updated model names for Gemini Live, including a new Vertex model as the default and a new AI Studio model option.

Co-authored-by: Hangfei Lin <hangfei@google.com>
PiperOrigin-RevId: 828515811
2025-11-05 09:57:59 -08:00
1265 changed files with 78322 additions and 13307 deletions
+3
View File
@@ -0,0 +1,3 @@
{
".": "1.24.1"
}
+52 -17
View File
@@ -7,34 +7,69 @@ assignees: ''
---
** Please make sure you read the contribution guide and file the issues in the right place. **
[Contribution guide.](https://google.github.io/adk-docs/contributing-guide/)
## 🔴 Required Information
*Please ensure all items in this section are completed to allow for efficient
triaging. Requests without complete information may be rejected / deprioritized.
If an item is not applicable to you - please mark it as N/A*
**Describe the bug**
**Describe the Bug:**
A clear and concise description of what the bug is.
**To Reproduce**
Please share a minimal code and data to reproduce your problem.
Steps to reproduce the behavior:
**Steps to Reproduce:**
Please provide a numbered list of steps to reproduce the behavior:
1. Install '...'
2. Run '....'
3. Open '....'
4. Provie error or stacktrace
4. Provide error or stacktrace
**Expected behavior**
**Expected Behavior:**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Observed Behavior:**
What actually happened? Include error messages or crash stack traces here.
**Desktop (please complete the following information):**
- OS: [e.g. macOS, Linux, Windows]
- Python version(python -V):
- ADK version(pip show google-adk):
**Environment Details:**
- ADK Library Version (pip show google-adk):
- Desktop OS:** [e.g., macOS, Linux, Windows]
- Python Version (python -V):
**Model Information:**
**Model Information:**
- Are you using LiteLLM: Yes/No
- Which model is being used(e.g. gemini-2.5-pro)
- Which model is being used: (e.g., gemini-2.5-pro)
**Additional context**
---
## 🟡 Optional Information
*Providing this information greatly speeds up the resolution process.*
**Regression:**
Did this work in a previous version of ADK? If so, which one?
**Logs:**
Please attach relevant logs. Wrap them in code blocks (```) or attach a
text file.
```text
// Paste logs here
```
**Screenshots / Video:**
If applicable, add screenshots or screen recordings to help explain
your problem.
**Additional Context:**
Add any other context about the problem here.
**Minimal Reproduction Code:**
Please provide a code snippet or a link to a Gist/repo that isolates the issue.
```python
// Code snippet here
```
**How often has this issue occurred?:**
- Always (100%)
- Often (50%+)
- Intermittently (<50%)
- Once / Rare
+33 -8
View File
@@ -10,14 +10,39 @@ assignees: ''
** Please make sure you read the contribution guide and file the issues in the right place. **
[Contribution guide.](https://google.github.io/adk-docs/contributing-guide/)
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
## 🔴 Required Information
*Please ensure all items in this section are completed to allow for efficient
triaging. Requests without complete information may be rejected / deprioritized.
If an item is not applicable to you - please mark it as N/A*
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
### Is your feature request related to a specific problem?
Please describe the problem you are trying to solve. (Ex: "I'm always frustrated
when I have to manually handle X...")
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
### Describe the Solution You'd Like
A clear and concise description of the feature or API change you want.
Be specific about input/outputs if this involves an API change.
**Additional context**
Add any other context or screenshots about the feature request here.
### Impact on your work
How does this feature impact your work and what are you trying to achieve?
If this is critical for you, tell us if there is a timeline by when you need
this feature.
### Willingness to contribute
Are you interested in implementing this feature yourself or submitting a PR?
(Yes/No)
---
## 🟡 Recommended Information
### Describe Alternatives You've Considered
A clear and concise description of any alternative solutions or workarounds
you've considered and why they didn't work for you.
### Proposed API / Implementation
If you have ideas on how this should look in code, please share a
pseudo-code example.
### Additional Context
Add any other context or screenshots about the feature request here.
+24
View File
@@ -0,0 +1,24 @@
{
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
"packages": {
".": {
"release-type": "python",
"package-name": "google-adk",
"include-component-in-tag": false,
"skip-github-release": true,
"changelog-path": "CHANGELOG.md",
"changelog-sections": [
{"type": "feat", "section": "Features"},
{"type": "fix", "section": "Bug Fixes"},
{"type": "perf", "section": "Performance Improvements"},
{"type": "refactor", "section": "Code Refactoring"},
{"type": "docs", "section": "Documentation"},
{"type": "test", "section": "Tests", "hidden": true},
{"type": "build", "section": "Build System", "hidden": true},
{"type": "ci", "section": "CI/CD", "hidden": true},
{"type": "style", "section": "Styles", "hidden": true},
{"type": "chore", "section": "Miscellaneous Chores", "hidden": true}
]
}
}
}
-5
View File
@@ -1,5 +0,0 @@
releaseType: python
handleGHRelease: true
bumpMinorPreMajor: false
extraFiles:
- src/google/adk/version.py
-1
View File
@@ -1 +0,0 @@
enabled: true
@@ -16,15 +16,15 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Load adk-bot SSH Private Key
uses: webfactory/ssh-agent@v0.9.0
uses: webfactory/ssh-agent@v0.9.1
with:
ssh-private-key: ${{ secrets.ADK_BOT_SSH_PRIVATE_KEY }}
+3 -3
View File
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 2
@@ -96,7 +96,7 @@ jobs:
echo ""
set +e
FILES_WITH_FORBIDDEN_IMPORT=$(grep -lE '^from.*cli.*import.*$' $CHANGED_FILES)
FILES_WITH_FORBIDDEN_IMPORT=$(grep -lE '^from.*\bcli\b.*import.*$' $CHANGED_FILES)
GREP_EXIT_CODE=$?
set -e
+1 -1
View File
@@ -25,7 +25,7 @@ jobs:
steps:
- name: Check for Copybara commits and close PRs
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
github-token: ${{ secrets.ADK_TRIAGE_AGENT }}
script: |
+3 -3
View File
@@ -15,16 +15,16 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Authenticate to Google Cloud
id: auth
uses: 'google-github-actions/auth@v2'
uses: 'google-github-actions/auth@v3'
with:
credentials_json: '${{ secrets.ADK_GCP_SA_KEY }}'
+4 -4
View File
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -26,14 +26,14 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 2
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.x'
python-version: '3.11'
- name: Install isort
run: |
+74
View File
@@ -0,0 +1,74 @@
name: Mypy New Error Check
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
mypy-diff:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12', '3.13',]
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Generate Baseline (Main)
run: |
# Switch to main branch to generate baseline
git checkout origin/main
git checkout ${{ github.sha }} -- pyproject.toml
# Install dependencies for main
uv venv .venv
source .venv/bin/activate
uv sync --all-extras
# Run mypy, filter for errors only, remove line numbers (file:123: -> file::), and sort
# We ignore exit code (|| true) because we expect errors on main
uv run mypy . | grep "error:" | sed 's/:\([0-9]\+\):/::/g' | sort > main_errors.txt || true
echo "Found $(wc -l < main_errors.txt) errors on main."
- name: Check PR Branch
run: |
# Switch back to the PR commit
git checkout ${{ github.sha }}
# Re-sync dependencies in case the PR changed them
source .venv/bin/activate
uv sync --all-extras
# Run mypy on PR code, apply same processing
uv run mypy . | grep "error:" | sed 's/:\([0-9]\+\):/::/g' | sort > pr_errors.txt || true
echo "Found $(wc -l < pr_errors.txt) errors on PR branch."
- name: Compare and Fail on New Errors
run: |
# 'comm -13' suppresses unique lines in file1 (main) and common lines,
# leaving only lines unique to file2 (PR) -> The new errors.
comm -13 main_errors.txt pr_errors.txt > new_errors.txt
if [ -s new_errors.txt ]; then
echo "::error::The following NEW mypy errors were introduced:"
cat new_errors.txt
exit 1
else
echo "Great job! No new mypy errors introduced."
fi
+32
View File
@@ -0,0 +1,32 @@
name: Mypy Type Check
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
mypy:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12', '3.13',]
steps:
- uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: uv sync --all-extras
- name: Run mypy
run: uv run mypy . --strict
+2 -2
View File
@@ -20,10 +20,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.11'
+4 -4
View File
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -26,14 +26,14 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 2
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.x'
python-version: '3.11'
- name: Install pyink
run: |
+8 -16
View File
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -25,19 +25,19 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install the latest version of uv
uses: astral-sh/setup-uv@v6
uses: astral-sh/setup-uv@v7
- name: Install dependencies
run: |
@@ -48,14 +48,6 @@ jobs:
- name: Run unit tests with pytest
run: |
source .venv/bin/activate
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
pytest tests/unittests \
--ignore=tests/unittests/artifacts/test_artifact_service.py \
--ignore=tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py
+46
View File
@@ -0,0 +1,46 @@
# Cherry-picks a commit from main to the release/candidate branch.
# Use this to include bug fixes in an in-progress release.
name: "Release: Cherry-pick"
on:
workflow_dispatch:
inputs:
commit_sha:
description: 'Commit SHA to cherry-pick'
required: true
type: string
permissions:
contents: write
actions: write
jobs:
cherry-pick:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: release/candidate
fetch-depth: 0
- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Cherry-pick commit
run: |
echo "Cherry-picking ${{ inputs.commit_sha }} to release/candidate"
git cherry-pick ${{ inputs.commit_sha }}
- name: Push changes
run: |
git push origin release/candidate
echo "Successfully cherry-picked commit to release/candidate"
- name: Trigger Release Please
env:
GH_TOKEN: ${{ github.token }}
run: |
gh workflow run release-please.yml --repo ${{ github.repository }}
echo "Triggered Release Please workflow"
+46
View File
@@ -0,0 +1,46 @@
# Starts the release process by creating a release/candidate branch.
# Triggers release-please to generate a changelog PR.
name: "Release: Cut"
on:
workflow_dispatch:
inputs:
commit_sha:
description: 'Commit SHA to cut from (leave empty for latest main)'
required: false
type: string
permissions:
contents: write
actions: write
jobs:
cut-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.commit_sha || 'main' }}
- name: Check for existing release/candidate branch
env:
GH_TOKEN: ${{ github.token }}
run: |
if git ls-remote --exit-code --heads origin release/candidate &>/dev/null; then
echo "Error: release/candidate branch already exists"
echo "Please finalize or delete the existing release candidate before starting a new one"
exit 1
fi
- name: Create and push release/candidate branch
run: |
git checkout -b release/candidate
git push origin release/candidate
echo "Created branch: release/candidate"
- name: Trigger Release Please
env:
GH_TOKEN: ${{ github.token }}
run: |
gh workflow run release-please.yml --repo ${{ github.repository }}
echo "Triggered Release Please workflow"
+66
View File
@@ -0,0 +1,66 @@
# Triggers when release-please PR is merged to release/candidate.
# Creates the final release/v{version} branch and deletes the candidate branch.
name: "Release: Finalize"
on:
pull_request:
types: [closed]
branches:
- release/candidate
permissions:
contents: write
pull-requests: write
jobs:
finalize:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Check for release-please PR
id: check
env:
LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }}
run: |
if echo "$LABELS" | grep -q "autorelease: pending"; then
echo "is_release_pr=true" >> $GITHUB_OUTPUT
else
echo "Not a release-please PR, skipping"
echo "is_release_pr=false" >> $GITHUB_OUTPUT
fi
- uses: actions/checkout@v4
if: steps.check.outputs.is_release_pr == 'true'
with:
ref: release/candidate
- name: Extract version from manifest
if: steps.check.outputs.is_release_pr == 'true'
id: version
run: |
VERSION=$(jq -r '.["."]' .github/.release-please-manifest.json)
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Extracted version: $VERSION"
- name: Create release branch
if: steps.check.outputs.is_release_pr == 'true'
run: |
git checkout -b "release/v${{ steps.version.outputs.version }}"
git push origin "release/v${{ steps.version.outputs.version }}"
echo "Created branch: release/v${{ steps.version.outputs.version }}"
- name: Delete release/candidate branch
if: steps.check.outputs.is_release_pr == 'true'
run: |
git push origin --delete release/candidate
echo "Deleted branch: release/candidate"
- name: Update PR label to tagged
if: steps.check.outputs.is_release_pr == 'true'
env:
GH_TOKEN: ${{ github.token }}
run: |
gh pr edit ${{ github.event.pull_request.number }} \
--remove-label "autorelease: pending" \
--add-label "autorelease: tagged"
echo "Updated PR label to autorelease: tagged"
+30
View File
@@ -0,0 +1,30 @@
# Runs release-please to create/update a PR with version bump and changelog.
# Triggered by pushes to release/candidate or manually.
name: "Release: Please"
on:
push:
branches:
- release/candidate
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
release-please:
# Skip if this is a release-please PR merge (handled by Release: Finalize)
if: "!startsWith(github.event.head_commit.message, 'chore(release')"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: release/candidate
- uses: googleapis/release-please-action@v4
with:
token: ${{ secrets.RELEASE_PAT }}
config-file: .github/release-please-config.json
manifest-file: .github/.release-please-manifest.json
target-branch: release/candidate

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