The append_event method had inconsistent timezone handling: SQLite
converted event.timestamp to UTC before stripping tzinfo, while all
other backends (including PostgreSQL) used datetime.fromtimestamp()
which produces naive datetimes in the server's local timezone.
On non-UTC servers, this caused PostgreSQL to store update_time values
offset by hours from SQLite, leading to incorrect staleness checks.
Now all backends first convert to UTC, then strip tzinfo only for
SQLite and PostgreSQL (which require naive datetimes).
https://claude.ai/code/session_01TNMxZwEdKgsQJvWtJhzQiQ
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
* 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
### 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
### 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
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
* **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
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
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
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
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
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
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
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
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
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
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
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
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
* Add back deprecated eval endpoint for web until we migrate([ae993e8](https://github.com/google/adk-python/commit/ae993e884f44db276a4116ebb7a11a2fb586dbfe))
* Breaking: Make credential manager accept `tool_context` instead of `callback_context` ([fe82f3c](https://github.com/google/adk-python/commit/fe82f3cde854e49be13d90b4c02d786d82f8a202))
### Highlights
* **[Web]**
* **Consolidated Event View**: Replaced the Event tab with a more intuitive "click-to-expand" interaction on message rows, enabling faster debugging within the chat context
* **Enhanced Accessibility**: Added full support for arrow-key navigation for a more seamless, keyboard-centric experience
* **Rich Developer Tooling**: Introduced detailed tooltips for function calls, providing instant visibility into arguments, responses, and state changes
* **A2UI Integration**: Integrated the **A2UI v0.8** standard catalog to automatically render spec-compliant ADK parts as native UI components directly in the chat
### Features
* **[Core]**
* Allow passthrough of `GOOGLE_CLOUD_LOCATION` for Agent Engine deployments ([004e15c](https://github.com/google/adk-python/commit/004e15ccb7c7f683623f8e7d2e77a9d12558c545))
* Add interface for agent optimizers ([4ee125a](https://github.com/google/adk-python/commit/4ee125a03856fdb9ed28245bf7f5917c2d9038db))
* Pass event ID as metadata when converted into a message ([85434e2](https://github.com/google/adk-python/commit/85434e293f7bd1e3711f190f84d5a36804e4462b))
* Restructure the bug report template as per the intake process ([324796b](https://github.com/google/adk-python/commit/324796b4fe05bec3379bfef67071a29552ef355a))
* **[Models]**
* Mark Vertex calls made from non-Gemini models ([7d58e0d](https://github.com/google/adk-python/commit/7d58e0d2f375bc80bdfac9cffea2926fd2344b8a))
* **[Evals]**
* Allow Vertex AI Client initialization with API Key ([43d6075](https://github.com/google/adk-python/commit/43d6075ea7aa49ddb358732f2219ca9598dd286f))
* Remove overall evaluation status calculation from `_CustomMetricEvaluator` and add threshold to custom metric function expected signature ([553e376](https://github.com/google/adk-python/commit/553e376718ceb3d7fb1403231bb720836d71f42c))
* **[Tools]**
* Make OpenAPI tool asynchronous ([9290b96](https://github.com/google/adk-python/commit/9290b966267dc02569786f95aab2a3cb78c7004f))
* Implement toolset authentication for `McpToolset`, `OpenAPIToolset`, and other toolsets ([798f65d](https://github.com/google/adk-python/commit/798f65df86b1bbe33d864e30c5b1f9e155e89810))
* Add framework support for toolset authentication before `get_tools` calls ([ee873ca](https://github.com/google/adk-python/commit/ee873cae2e2df960910d264a4340ce6c0489eb7a))
* Support dynamic configuration for `VertexAiSearchTool` ([585ebfd](https://github.com/google/adk-python/commit/585ebfdac7f1b8007b4e4a7e4258ec5de72c78b1))
* Add `get_auth_config` method to toolset to expose authentication requirements ([381d44c](https://github.com/google/adk-python/commit/381d44cab437cac027af181ae627e7b260b7561e))
* Add methods in `McpToolset` for users to access MCP resources ([8f7d965](https://github.com/google/adk-python/commit/8f7d9659cfc19034af29952fbca765d012169b38))
* Improve error message when failing to get tools from MCP ([3480b3b](https://github.com/google/adk-python/commit/3480b3b82d89de69f77637d7ad034827434df45a))
* **[Services]**
* Improve `asyncio` loop handling and test cleanup ([00aba2d](https://github.com/google/adk-python/commit/00aba2d884d24fb5244d1de84f8dba9cbc3c07e8))
* **[Live]**
* Support running tools in separate threads for live mode ([714c3ad](https://github.com/google/adk-python/commit/714c3ad0477e775fba6696a919a366a293197268))
* **[Observability]**
* Add extra attributes to spans generated with `opentelemetry-instrumentation-google-genai` ([e87a843](https://github.com/google/adk-python/commit/e87a8437fb430e0d4c42c73948e3ba1872040a15))
### Bug Fixes
* Ignore `session_db_kwargs` for SQLite session services ([ce07cd8](https://github.com/google/adk-python/commit/ce07cd8144c8498434f68e61ebeb519bf329f778))
* Resolve `MutualTLSChannelError` by adding `pyopenssl` dependency ([125bc85](https://github.com/google/adk-python/commit/125bc85ac5e1400bc38f7c681f76fa82626c9911))
* Add `update_timestamp_tz` property to `StorageSession` ([666cebe](https://github.com/google/adk-python/commit/666cebe3693d2981fd5fea6e9e4c65e56dcd3f2b))
* Do not treat Function Calls and Function Responses as invisible when marked as thoughts ([853a3b0](https://github.com/google/adk-python/commit/853a3b0e143ce27516f0de51e0e0df2af6ecf465))
* Add pre-deployment validation for agent module imports (credit to @ppgranger, [2ac468e](https://github.com/google/adk-python/commit/2ac468ea7e30ef30c1324ffc86f67dbf32ab7ede))
* Fix cases where `execution_result_delimiters` have `None` type element ([a16e3cc](https://github.com/google/adk-python/commit/a16e3cc67e1cb391228ba78662547672404ae550))
* Disable `save_input_blobs_as_artifacts` deprecation warning message for users not setting it ([c34615e](https://github.com/google/adk-python/commit/c34615ecf3c7bbe0f4275f72543774f258c565b4))
* Add `pypika>=0.50.0` to `project.toml` to support `crewai` on Python 3.12+ ([e8f7aa3](https://github.com/google/adk-python/commit/e8f7aa3140d2585ac38ebfe31c5b650383499a20))
* Update OpenTelemetry dependency versions to relax version constraints for `opentelemetry-api` and `opentelemetry-sdk` ([706a6dd](https://github.com/google/adk-python/commit/706a6dda8144da147bd9fa42ef85bbfa58fec5d3))
* Enable `pool_pre_ping` by default for non-SQLite database engines ([da73e71](https://github.com/google/adk-python/commit/da73e718efa9557ed33e2fb579de68fcbcf4c7f0))
* Ensure database sessions are always rolled back on errors ([63a8eba](https://github.com/google/adk-python/commit/63a8eba53f2cb07625eb7cd111ff767e8e0030fa))
* Reload stale session in `DatabaseSessionService` when storage update time is later than the in-memory session object ([1063fa5](https://github.com/google/adk-python/commit/1063fa532cad59d8e9f7421ce2f523724d49d541))
* Make credential key generation stable and prevent cross-user credential leaks ([33012e6](https://github.com/google/adk-python/commit/33012e6dda9ef20c7a1dae66a84717de5d782097))
* Change MCP `read_resource` to return original contents ([ecce7e5](https://github.com/google/adk-python/commit/ecce7e54a688a915a1b9d742c39e4684186729be))
* Recognize function responses as non-empty parts in LiteLLM ([d0102ec](https://github.com/google/adk-python/commit/d0102ecea331e062190dbb7578a4ef7f4044306e))
* Handle HTTP/HTTPS URLs for media files in LiteLLM content conversion ([47221cd](https://github.com/google/adk-python/commit/47221cd5c1e778cd4b92ed8d382c639435f5728c))
* Fix Pydantic schema generation error for `ClientSession` ([131fbd3](https://github.com/google/adk-python/commit/131fbd39482980572487a30fea13236d2badd543))
* Fix Click’s Wrapping in `adk eval` help message ([3bcd8f7](https://github.com/google/adk-python/commit/3bcd8f7f7a0683f838005bc209f7d39dc93f850b))
* Stream errors as simple JSON objects in ADK web server SSE endpoint ([798d005](https://github.com/google/adk-python/commit/798d0053c832e7ed52e2e104f8a14f789ba8b17f))
* Improve error handling for LiteLLM import in `gemma_llm.py` ([574ec43](https://github.com/google/adk-python/commit/574ec43a175e3bf3a05e73114e8db7196fae7040))
* Replace proxy methods with utils implementation ([6ff10b2](https://github.com/google/adk-python/commit/6ff10b23be01c1f7dd79d13ac8c679c079140f76), [f82ceb0](https://github.com/google/adk-python/commit/f82ceb0ce75d3efed7c046835ddac76c28210013))
* Replace print statements with logging in ADK evaluation components ([dd8cd27](https://github.com/google/adk-python/commit/dd8cd27b2ce505ecca50cdfbb1469db01c82b0af))
* Add sample agent that requires OAuth flow during MCP tool listing, and convert `MCPToolset` to `McpToolset` in unit tests ([2770012](https://github.com/google/adk-python/commit/2770012cecdfc71628a818a75b21faabe828b4e5), [4341839](https://github.com/google/adk-python/commit/43418394202c2d01b0d37f6424bd601148077e27))
* Ensure `BigQueryAgentAnalyticsPlugin` is shut down after each test ([c0c98d9](https://github.com/google/adk-python/commit/c0c98d94b3161d6bf9fff731e0abfc985b53e653))
* Add ADK logger in `RestApiTool` ([288c2c4](https://github.com/google/adk-python/commit/288c2c448d77c574dafadf7851a49e6ff59fa7f4))
* Add GitHub Action check to run `mypy` ([32f9f92](https://github.com/google/adk-python/commit/32f9f92042ab530220ac9d159045c91d311affa7))
* Add `unittests.sh` script and update `CONTRIBUTING.md` ([025b42c](https://github.com/google/adk-python/commit/025b42c8361ad2078593e3e7fc5301df88a532c7))
* Extract helper function for LLM request building and response processing ([753084f](https://github.com/google/adk-python/commit/753084fd46c9637488f33b0a05b4d270f6e03a39))
* Breaking: Use OpenTelemetry for BigQuery plugin tracing, replacing custom `ContextVar` implementation ([ab89d12](https://github.com/google/adk-python/commit/ab89d1283430041afb303834749869e9ee331721))
### Features
* **[Core]**
* Add support to automatically create a session if one does not exist ([8e69a58](https://github.com/google/adk-python/commit/8e69a58df4eadeccbb100b7264bb518a46b61fd7))
* Remove `@experimental` decorator from `AgentEngineSandboxCodeExecutor` ([135f763](https://github.com/google/adk-python/commit/135f7633253f6a415302142abc3579b664601d5b))
* Add `--disable_features` CLI option to override default feature enable state ([53b67ce](https://github.com/google/adk-python/commit/53b67ce6340f3f3f8c3d732f9f7811e445c76359))
* Add `otel_to_cloud` flag to `adk deploy agent_engine` command ([21f63f6](https://github.com/google/adk-python/commit/21f63f66ee424501d9a70806277463ef718ae843))
* Add `is_computer_use` field to agent information in `adk-web` server ([5923da7](https://github.com/google/adk-python/commit/5923da786eb1aaef6f0bcbc6adc906cbc8bf9b36))
* Allow `thinking_config` in `generate_content_config` ([e162bb8](https://github.com/google/adk-python/commit/e162bb8832a806e2380048e39165bf837455f88c))
* Convert A2UI messages between A2A `DataPart` metadata and ADK events ([1133ce2](https://github.com/google/adk-python/commit/1133ce219c5a7a9a85222b03e348ba6b13830c8f))
* Add `--enable_features` CLI option to override default feature enable state ([79fcddb](https://github.com/google/adk-python/commit/79fcddb39f71a4c1342e63b4d67832b3eccb2652))
* **[Tools]**
* Add flush mechanism to `BigQueryAgentAnalyticsPlugin` to ensure pending log events are written to BigQuery ([9579bea](https://github.com/google/adk-python/commit/9579bea05d946b3d8b4bfec35e510725dd371224))
* Allow Google Search tool to set a different model ([b57a3d4](https://github.com/google/adk-python/commit/b57a3d43e4656f5a3c5db53addff02b67d1fde26))
* Support authentication for MCP tool listing ([e3d542a](https://github.com/google/adk-python/commit/e3d542a5ba3d357407f8cd29cfdd722f583c8564) [19315fe](https://github.com/google/adk-python/commit/19315fe557039fa8bf446525a4830b1c9f40cba9))
* Use JSON schema for `base_retrieval_tool`, `load_artifacts_tool`, and `load_memory_tool` declarations when the feature is enabled ([69ad605](https://github.com/google/adk-python/commit/69ad605bc4bbe9a4f018127fd3625169ee70488e))
* Use JSON schema for `IntegrationConnectorTool` declaration when the feature is enabled ([2ed6865](https://github.com/google/adk-python/commit/2ed686527ac75ff64128ce7d9b1a3befc2b37c64))
* Start and close `ClientSession` in a single task in `McpSessionManager` ([cce430d](https://github.com/google/adk-python/commit/cce430da799766686e65f6cae02ba64e916d5c8a))
* Use JSON schema for `RestApiTool` declaration when the feature is enabled ([a5f0d33](https://github.com/google/adk-python/commit/a5f0d333d7f26f2966ed511d5d9def7a1933f0c2))
* **[Evals]**
* Update `adk eval` CLI to consume custom metrics by adding `CustomMetricEvaluator` ([ea0934b](https://github.com/google/adk-python/commit/ea0934b9934c1fefd129a1026d6af369f126870e))
* Update `EvalConfig` and `EvalMetric` data models to support custom metrics ([6d2f33a](https://github.com/google/adk-python/commit/6d2f33a59cfba358dd758378290125fc2701c411))
* **[Observability]**
* Add minimal `generate_content {model.name}` spans and logs for non-Gemini inference and when `opentelemetry-inference-google-genai` dependency is missing ([935c279](https://github.com/google/adk-python/commit/935c279f8281bde99224f03d936b8abe51cbabfc))
* Persist user input content to session in live mode ([a04828d](https://github.com/google/adk-python/commit/a04828dd8a848482acbd48acc7da432d0d2cb0aa))
### Bug Fixes
* Recursively extract input/output schema for AgentTool ([bf2b56d](https://github.com/google/adk-python/commit/bf2b56de6d0052e40b6d871b2d22c56e9225e145))
* Yield buffered `function_call` and `function_response` events during live streaming ([7b25b8f](https://github.com/google/adk-python/commit/7b25b8fb1daf54d7694bf405d545d46d2c012d2b))
* Update `authlib` and `mcp` dependency versions ([7955177](https://github.com/google/adk-python/commit/7955177fb28b8e5dc19aae8be94015a7b5d9882a))
* Set `LITELLM_MODE` to `PRODUCTION` before importing LiteLLM to prevent implicit `.env` file loading ([215c2f5](https://github.com/google/adk-python/commit/215c2f506e21a3d8c39551b80f6356943ecae320))
* Redact sensitive information from URIs in logs ([5257869](https://github.com/google/adk-python/commit/5257869d91a77ebd1381538a85e7fdc3a600da90))
* Handle asynchronous driver URLs in the migration tool ([4b29d15](https://github.com/google/adk-python/commit/4b29d15b3e5df65f3503daffa6bc7af85159507b))
* Remove custom metadata from A2A response events ([81eaeb5](https://github.com/google/adk-python/commit/81eaeb5eba6d40cde0cf6147d96921ed1bf7bb31))
* Handle `None` inferences in eval results ([7d4326c](https://github.com/google/adk-python/commit/7d4326c3606a7ff2ba3c0fdef08d4f6af52ee71e))
* Mark all parts of a thought event as thought ([f92d4e3](https://github.com/google/adk-python/commit/f92d4e397f37445fe9032a95ce26646a3a69300b))
* Use `json.dumps` for error messages in SSE events ([6ad18cc](https://github.com/google/adk-python/commit/6ad18cc2fc3a3315a0fc240cb51b3283b53116b4))
* Use the correct path for config-based agents when deploying to AgentEngine ([83d7bb6](https://github.com/google/adk-python/commit/83d7bb6ef0d952ad04c5d9a61aaf202672c7e17d))
* Support Generator and Async Generator tool declarations in JSON schema ([19555e7](https://github.com/google/adk-python/commit/19555e7dce6d60c3b960ca0bc2f928c138ac3cc0) [7c28297](https://github.com/google/adk-python/commit/7c282973ea193841fee79f90b8a91c5e02627ccc))
* Prevent stopping event processing on events with `None` content ([ed2c3eb](https://github.com/google/adk-python/commit/ed2c3ebde9cafbb5e2bf375f44db1e77cee9fb24))
* Fix `'NoneType'` object is not iterable error ([7db3ce9](https://github.com/google/adk-python/commit/7db3ce9613b1c2c97e6ca3cd8115736516dc1556))
* Use canonical tools to find streaming tools and register them by `tool.name` ([ec6abf4](https://github.com/google/adk-python/commit/ec6abf401019c39e8e1a8d1b2c7d5cf5e8c7ac56))
* Initialize `self._auth_config` inside `BaseAuthenticatedTool` to access authentication headers in `McpTool` ([d4da1bb](https://github.com/google/adk-python/commit/d4da1bb7330cdb87c1dcbe0b9023148357a6bd07))
* Only filter out audio content when sending history ([712b5a3](https://github.com/google/adk-python/commit/712b5a393d44e7b5ce35fc459da98361bae4bb16))
* Add finish reason mapping and remove custom file URI handling in LiteLLM ([89bed43](https://github.com/google/adk-python/commit/89bed43f5e0c5ad12dd31c716d372145b7e33e78))
* Convert unsupported inline artifact MIME types to text in `LoadArtifactsTool` ([fdc98d5](https://github.com/google/adk-python/commit/fdc98d5c927bfef021e87cf72103892e4c2ac12a))
* Pass `log_level` to `uvicorn` in `web` and `api_server` commands ([38d52b2](https://github.com/google/adk-python/commit/38d52b247600fb45a2beeb041c4698e90c00d705))
* Use the agent name as the author of the audio event ([ab62b1b](https://github.com/google/adk-python/commit/ab62b1bffd7ad2df5809d430ad1823872b8bd67a))
* Handle `NOT_FOUND` error when fetching Vertex AI sessions ([75231a3](https://github.com/google/adk-python/commit/75231a30f1857d930804769caf88bcc20839dd08))
* Fix `httpx` client closure during event pagination ([b725045](https://github.com/google/adk-python/commit/b725045e5a1192bc9fd5190cbd2758ab6ff02590))
### Improvements
* Add new conversational analytics API toolset ([82fa10b](https://github.com/google/adk-python/commit/82fa10b71e037b565cb407c82e9e908432dab0ff))
* Filter out `adk_request_input` event from content list ([295b345](https://github.com/google/adk-python/commit/295b34558774d1f64022009980e3edd8eb79527b))
* Always skip executing partial function calls ([d62f9c8](https://github.com/google/adk-python/commit/d62f9c896c301aba3a781e868735e16f946a8862))
* Update comments of request confirmation preprocessor ([1699b09](https://github.com/google/adk-python/commit/1699b090edc9e5b13c34f461c8e664187157c5c0))
* Fix various typos ([a8f2ddd](https://github.com/google/adk-python/commit/a8f2ddd943301bbf53f49b3a23300ece45803cc0))
* Update sample live streaming tools agent to use latest live models ([3dd7e3f](https://github.com/google/adk-python/commit/3dd7e3f1b9be05c28adb061864d84c4202a2d922))
* Make the regex to catch CLI reference strict by adding word boundary anchor ([c222a45](https://github.com/google/adk-python/commit/c222a45ef74f7b55c48dc151ba98cd8c30a15c57))
* Migrate `ToolboxToolset` to use `toolbox-adk` and align validation ([7dc6adf](https://github.com/google/adk-python/commit/7dc6adf4e563330a09e4cf28d2b1994c24b007d1) [277084e](https://github.com/google/adk-python/commit/277084e31368302e6338b69d456affd35d5fedfe))
* Always log API backend when connecting to live model ([7b035aa](https://github.com/google/adk-python/commit/7b035aa9fc43a43489aeffea8f877cd7eaa09f35))
* Add a sample BigQuery agent using BigQuery MCP tools ([672b57f](https://github.com/google/adk-python/commit/672b57f1b76580023d1f348de76227291a9c1012))
* Add a `DebugLoggingPlugin` to record human-readable debugging logs ([8973618](https://github.com/google/adk-python/commit/8973618b0b0e90c513873e22af272c147efb4904))
* Upgrade the sample BigQuery agent model version to `gemini-2.5-flash` ([fd2c0f5](https://github.com/google/adk-python/commit/fd2c0f556b786417a9f6add744827b07e7a06b7d))
* Import `migration_runner` lazily within the migrate command ([905604f](https://github.com/google/adk-python/commit/905604faac82aca8ae0935eebea288f82985e9c5))
* Make `LlmAgent.model` optional with a default fallback ([b287215](https://github.com/google/adk-python/commit/b28721508a41bf6bcfef52bbc042fb6193a32dfa)).
* Support regex for allowed origins ([2ea6e51](https://github.com/google/adk-python/commit/2ea6e513cff61d3f330274725c66f82fce4ba259)).
* Enable PROGRESSIVE_SSE_STREAMING feature by default ([0b1cff2](https://github.com/google/adk-python/commit/0b1cff2976d1c04acf3863f76107b05d1cec448f)).
* **[Evals]**
* Add custom instructions support to LlmBackedUserSimulator ([a364388](https://github.com/google/adk-python/commit/a364388d9744969760fd87ed24d60793146c162a)).
* Introduce a post-hoc, per-turn evaluator for user simulations ([e515e0f](https://github.com/google/adk-python/commit/e515e0f321a259016c5e5f6b388ecf02ae343ba7)).
* Add a handwritten tool for Cloud Pub/Sub ([b6f6dcb](https://github.com/google/adk-python/commit/b6f6dcbeb465a775b9c38ace7a324ee2155d366f)).
* Add `token_endpoint_auth_method` support to OAuth2 credentials ([8782a69](https://github.com/google/adk-python/commit/8782a695036aa0c1528027673868159143f925f0)).
* **[Services]**
* Introduce new JSON-based database schema for DatabaseSessionService, which will be used for newly-created databases. A migration command and script are provided.([7e6ef71](https://github.com/google/adk-python/commit/7e6ef71eec8be2e804286cc4140d0cbdf84f1206) [ba91fea](https://github.com/google/adk-python/commit/ba91fea54136ab60f37c10b899c3648d0b0fa721) [ce64787](https://github.com/google/adk-python/commit/ce64787c3e1130d1678e408aa31011fc88590e15)).
* Set log level when deploying to Agent Engine ([1f546df](https://github.com/google/adk-python/commit/1f546df35a1c18aeb3d2fc7a2ac66edf386027c5)).
* **[A2A]**
* Update event_converter used in A2ARemote agent to use a2a_task.status.message only if parts are non-empty ([e4ee9d7](https://github.com/google/adk-python/commit/e4ee9d7c46b57eed8493539d8f539c042bdfae60)).
### Bug Fixes
* Add checks for event content and parts before accessing ([5912835](https://github.com/google/adk-python/commit/5912835c975673c8fc2fb315150f5ec29d685eac)).
* Validate app name in `adk create` command ([742c926](https://github.com/google/adk-python/commit/742c9265a260a9c598a1f65e0996d926b4b9c022)).
* Prevent .env files from overriding existing environment variables ([0827d12](https://github.com/google/adk-python/commit/0827d12ccd74feb24758f64f2884c9493001b4ca)).
* Prevent ContextFilterPlugin from creating orphaned function responses ([e32f017](https://github.com/google/adk-python/commit/e32f017979e26a94b998311cafcde753fd29e44e)).
* Update empty event check to include executable code and execution results ([688f48f](https://github.com/google/adk-python/commit/688f48fffb9df6ef18a692cd2ccaa7628f4c82a7)).
* Make the BigQuery analytics plugin work with agents that don't have instructions such as the LoopAgent ([8bed01c](https://github.com/google/adk-python/commit/8bed01cbdc5961c0d219fd6389f492f1a4235de5)).
* Label response as thought if task is immediately returned as working ([4f3b733](https://github.com/google/adk-python/commit/4f3b733074c867e68ca5d38720ccb1f3e0b0d960)).
* Move and enhance the deprecation warning for the plugins argument in "_validate_runner_params" to the beginning of the function ([43270bc](https://github.com/google/adk-python/commit/43270bcb6197526ba5765f83d7e4fb88f213b8d3)).
* Oauth refresh not triggered on token expiry ([69997cd](https://github.com/google/adk-python/commit/69997cd5ef44ee881a974bb36dc100e17ed6de2e)).
* Fix double JSON encoding when saving eval set results ([fc4e3d6](https://github.com/google/adk-python/commit/fc4e3d6f607032259e68e91bcb1ad0815a03164e)).
* Allow string values for ToolTrajectoryCriterion.match_type ([93d6e4c](https://github.com/google/adk-python/commit/93d6e4c888d5a2181e3c22da049d8be0d6ead70c)).
* Fix inconsistent method signatures for evaluate_invocations ([0918b64](https://github.com/google/adk-python/commit/0918b647df6f88b95974d486a3161121a6514901)).
* Honor the modalities parameter in adk api server for live API ([19de45b](https://github.com/google/adk-python/commit/19de45b3250d09b9ec16c45788e7d472b3e588c2)).
* Filter out thought parts in lite_llm._get_content ([1ace8fc](https://github.com/google/adk-python/commit/1ace8fc6780bc25e2ef4222c73bc2558082b0a00)).
* Rehydration of EventActions in StorageEvent.to_event ([838530e](https://github.com/google/adk-python/commit/838530ebe053e5193d4329c5a203ca3d096ff7be)).
* Heal missing tool results before LiteLLM requests ([6b7386b](https://github.com/google/adk-python/commit/6b7386b7620bbc51cda8c1c6d9914549536640e6)).
* Refine Ollama content flattening and provider checks ([c6f389d](https://github.com/google/adk-python/commit/c6f389d4bc4d2b91795003a3bd87ed1f1b854493)).
* Add MIME type inference and default for file URIs in LiteLLM ([5c4bae7](https://github.com/google/adk-python/commit/5c4bae7ff2085c05b7f002f5fa368e9b48a752b1)).
* Use mode='json' in model_dump to serialize bytes correctly when using telemetry ([96c5db5](https://github.com/google/adk-python/commit/96c5db5a07f7f851751ccd68f176dad1634885cb)).
* Avoid local .adk storage in Cloud Run/GKE ([b30c2f4](https://github.com/google/adk-python/commit/b30c2f4e139e0d4410c5f8dd61acee2056ad06ea)).
* Remove fallback to cached exchanged credential in _load_existing_credential ([1ae0e16](https://github.com/google/adk-python/commit/1ae0e16b2c1a3139b9c2b1c4a3e725833a6240be)).
* Handle overriding of requirements when deploying to agent engine ([38a30a4](https://github.com/google/adk-python/commit/38a30a44d222fade8616f9d63410b1c2b6f84e1b)).
* Built-in agents (names starting with "__") now use in-memory session storage instead of creating .adk folders in the agents directory ([e3bac1a](https://github.com/google/adk-python/commit/e3bac1ab8c724454fb433cc7e78416b61efe33ee)).
* Change error_message column type to TEXT in DatabaseSessionService ([8335f35](https://github.com/google/adk-python/commit/8335f35015c7d4349bc4ac47dedbe99663b78e62)).
* Add schema type sanitization to OpenAPI spec parser ([6dce7f8](https://github.com/google/adk-python/commit/6dce7f8a8f28de275b1119fc03219f1468bb883b)).
* Prevent retry_on_errors from retrying asyncio.CancelledError ([30d3411](https://github.com/google/adk-python/commit/30d3411d603f12ca5bcdd2d71773d087f3191dba)).
* Include back-ticks around the BQ asset names in the tools examples ([8789ad8](https://github.com/google/adk-python/commit/8789ad8f16dfa250fab607946250a2857a25d5ef)).
* Fix issue with MCP tools throwing an error ([26e77e1](https://github.com/google/adk-python/commit/26e77e16947aed1abcfdd7f526532a708f1f073b)).
* Exclude thought parts when merging agent output ([07bb164](https://github.com/google/adk-python/commit/07bb1647588a781e701257c4c379736537029ea0)).
* Prepend "https://" to the MCP server url only if it doesn't already have a scheme ([71b3289](https://github.com/google/adk-python/commit/71b32890f5ab279e2bed1fd28c0f4693cba3f45e)).
* Split SSE events with both content and artifactDelta in ADK Web Server ([084fcfa](https://github.com/google/adk-python/commit/084fcfaba52c4a6075397221dbe7aba2f2acd2d7)).
* Propagate RunConfig custom metadata to all events ([e3db2d0](https://github.com/google/adk-python/commit/e3db2d0d8301748c63bad826f24692448dbd1c2c)).
* Ignore adk-bot administrative actions in stale agent ([3ec7ae3](https://github.com/google/adk-python/commit/3ec7ae3b8d532ed4b60786201a78e980dfc56cf3)).
* Only prepend "https://" to the MCP server url if it doesn't already have a scheme ([71b3289](https://github.com/google/adk-python/commit/71b32890f5ab279e2bed1fd28c0f4693cba3f45e)).
* Check all content parts for emptiness in _contains_empty_content ([f35d129](https://github.com/google/adk-python/commit/f35d129b4c59d381e95418725d6eaa072ca7720a)).
### Improvements
* Remove unnecessary event loop creation in LiveRequstQueue constructor ([ecc9f18](https://github.com/google/adk-python/commit/ecc9f182e3bd25ee8eda8920d665e967517ca59a)).
* Close database engines to avoid aiosqlite pytest hangs ([4ddb2cb](https://github.com/google/adk-python/commit/4ddb2cb2a8d1d026a43418b2dd698e6ea199594e)).
* Add `override_feature_enabled` to override the default feature enable states ([a088506](https://github.com/google/adk-python/commit/a0885064b0cbef3b25484025da0748dc64320d4a)).
* Move SQLite migration script to migration/ folder ([e8ab7da](https://github.com/google/adk-python/commit/e8ab7dafa96d5890a4fff919b9fa180993ef5830)).
* Update latest Live Model names for sample agent ([f1eb1c0](https://github.com/google/adk-python/commit/f1eb1c0254802ef3aa64c76512e3104376291ec0)).
* Update google-genai and google-cloud-aiplatform versions ([d58ea58](https://github.com/google/adk-python/commit/d58ea589ade822894f1482fd505a33d842755d9c)).
* Introduce MetricInfoProvider interface, and refactor metric evaluators to use this interface to provide MetricInfo ([5b7c8c0](https://github.com/google/adk-python/commit/5b7c8c04d6e4a688c76fa517922488e3d96353a3)).
* Update _flatten_ollama_content return type and add tests ([fcea86f](https://github.com/google/adk-python/commit/fcea86f58c95894bc9c1fb7ed12e36ddedaaa88a)).
* Add disambiguation message to enterprise_search_tool ([8329fec](https://github.com/google/adk-python/commit/8329fec0fc6b6130ffd1f53a8a2e2ccc6e8f43ed)).
* Add x-goog-user-project header to http calls in API Registry ([0088b0f](https://github.com/google/adk-python/commit/0088b0f3adb963dded692929c314d94709dcc211)).
* Set the default response modality to AUDIO only ([a4b914b](https://github.com/google/adk-python/commit/a4b914b09fbab76834050a8c8f0eb335b12cfc34)).
* Set `max_output_tokens` for the agent builder ([2e2d61b](https://github.com/google/adk-python/commit/2e2d61b6fecb90cd474d6f51255678ff74b67a9b))
* Set default response modality to AUDIO in run_session ([68402bd](https://github.com/google/adk-python/commit/68402bda49083f2d56f8e8488fe13aa58b3bc18c))
* Update remote_a2a_agent to better handle streaming events and avoid duplicate responses ([8e5f361](https://github.com/google/adk-python/commit/8e5f36126498f751171bb2639c7f5a9e7dca2558))
* Update the load_artifacts tool so that the model can reliably call it for followup questions about the same artifact ([238472d](https://github.com/google/adk-python/commit/238472d083b5aa67551bde733fc47826ff062679))
* Update the load_artifacts tool so that the model can reliably call it for follow-up questions about the same artifact ([238472d](https://github.com/google/adk-python/commit/238472d083b5aa67551bde733fc47826ff062679))
* Handle `App` instances returned by `agent_loader.load_agent` ([847df16](https://github.com/google/adk-python/commit/847df1638cbf1686aa43e8e094121d4e23e40245))
@@ -611,7 +873,7 @@
* AgentTool returns last content, instead of the content in the last event [bcf0dda](https://github.com/google/adk-python/commit/bcf0dda8bcc221974098f3077007c9e84c63021a)
* Updating BaseAgent.clone() and LlmAgent.clone() to properly clone fields that are lists [29bb75f](https://github.com/google/adk-python/commit/29bb75f975fe0c9c9d9a7e534a9c20158e1cbe1e)
* Make tool description for bigquery `execute_sql` for various write modes selfcontained [167182b](https://github.com/google/adk-python/commit/167182be0163117f814c70f453d5b2e19bf474df)
* Make tool description for bigquery `execute_sql` for various write modes self-contained [167182b](https://github.com/google/adk-python/commit/167182be0163117f814c70f453d5b2e19bf474df)
* Set invocation_id and branch for event generated when both output_schema and tools are used [3f3aa7b](https://github.com/google/adk-python/commit/3f3aa7b32d63cae5750d71bc586c088427c979ea)
* Rework parallel_agent.py to always aclose async generators [826f554](https://github.com/google/adk-python/commit/826f5547890dc02e707be33a3d6a58b527dac223)
* Add table metadata info into Spanner tool `get_table_schema` and fix the key usage info [81a53b5](https://github.com/google/adk-python/commit/81a53b53d6336011187a50ae8f1544de9b2764a8)
Define a multi-agent system with coordinator agent, greeter agent, and task execution agent. Then ADK engine and the model will guide the agents works together to accomplish the task.
Define a multi-agent system with coordinator agent, greeter agent, and task execution agent. Then ADK engine and the model will guide the agents to work together to accomplish the task.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.