Compare commits

..

104 Commits

Author SHA1 Message Date
Kathy Wu 7cf1e447d7 chore: Bumps version to v1.23.0 and updates CHANGELOG.md
Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 859790616
2026-01-22 15:03:52 -08:00
Xuan Yang 3f1b0d0957 chore: minor fix for DebugLoggingPlugin example
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 859762221
2026-01-22 14:00:17 -08:00
Max Ind 935c279f82 feat(otel): add minimal generate_content {model.name} spans and logs for non-gemini inference and when opentelemetry-inference-google-genai dependency is missing
Co-authored-by: Max Ind <maxind@google.com>
PiperOrigin-RevId: 859667045
2026-01-22 10:18:06 -08:00
Google Team Member 82fa10b71e feat: add new conversational analytics api tool set
PiperOrigin-RevId: 859449435
2026-01-21 23:31:37 -08:00
Xuan Yang bf2b56de6d fix: recursively extract input/output schema for AgentTool
Fixes: https://github.com/google/adk-python/issues/4154

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

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

### Link to Issue or Description of Change

N/A

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

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

**Problem:**

See above

**Solution:**
Fixing the typos

### Testing Plan

N/A

**Unit Tests:**

N/A

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

N/A

### Checklist

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

### Additional context

N/A

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

**Please ensure you have read the [contribution guide](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) before creating a pull request.**

### Link to Issue or Description of Change

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

Allow google search tool to set different model #4135

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

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

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

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

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

### Testing Plan

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

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

**Unit Tests:**

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

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

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

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

### Checklist

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

### Additional context

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

Key changes:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

### Link to Issue or Description of Change

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

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

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

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

**Problem:**

Trying to improve overall repo quality

**Solution:**

Fixing typos as they get discovered

### Testing Plan

N/A

**Unit Tests:**

N/A

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

N/A

### Checklist

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

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

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

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

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

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

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

Fixes #4176

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

* formatted via isort

---------

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

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

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

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

### Testing Plan

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

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

### Checklist

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

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

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

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

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

 Closes: #4108
 Tagging @invictus2010 for visibility.

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

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

### Link to Issue or Description of Change

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

- Closes: #3961

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

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

### Testing Plan

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

_Please describe the tests that you ran to verify your changes. This is required
for all PRs that are not small documentation or typo fixes._

**Unit Tests:**

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

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

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

_Please provide instructions on how to manually test your changes, including any
necessary setup or configuration. Please provide logs or screenshots to help
reviewers better understand the fix._

### Checklist

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

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

### Link to Issue or Description of Change

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

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

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

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

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

```

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

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

**Unit Tests:**

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

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

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

### Checklist

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

### Additional context
N/A

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

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

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

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

**Please ensure you have read the [contribution guide](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) before creating a pull request.**

### Link to Issue or Description of Change

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

- Closes:
  - #3950
  - #3731
  - #3708

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

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

**Solution:**

I Suggest 2 changes:

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

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

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

**Unit Tests:**

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

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

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

_Please provide instructions on how to manually test your changes, including any
necessary setup or configuration. Please provide logs or screenshots to help
reviewers better understand the fix._

### Checklist

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

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

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

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

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

Close #4125

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

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

Close #4028

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

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

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

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

**Please ensure you have read the [contribution guide](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) before creating a pull request.**

### Link to Issue or Description of Change

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

**Problem:**

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

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

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

**Solution:**

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

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

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

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

### Testing Plan

**Unit Tests:**

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

**pytest results:**

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

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

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

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

### Testing Plan

**Unit Tests:**

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

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

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

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

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

### Checklist

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

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

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

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

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

move event iteration inside api_client context in get_session

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

**Please ensure you have read the [contribution guide](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) before creating a pull request.**

### Link to Issue or Description of Change

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

- Closes: #3757

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

**Problem:**

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

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

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

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

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

**Solution:**

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

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

### Testing Plan

**Unit Tests:**

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

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

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

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

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

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

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

### Checklist

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

### Additional context

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

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

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

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

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

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

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

Close #4094

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

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

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

### Testing Plan

**Unit Tests:**

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

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

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

### Checklist

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

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

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

Close #4038

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

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

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

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

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

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

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

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

Related to issue #3715

**Please ensure you have read the [contribution guide](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) before creating a pull request.**

### Link to Issue or Description of Change

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

- Closes: #3715
- Related: #3715

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

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

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

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

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

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

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

### Testing Plan

_Please describe the tests that you ran to verify your changes. This is required
for all PRs that are not small documentation or typo fixes._

**Unit Tests:**

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

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

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

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

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

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

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

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

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

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

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

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

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

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

### Checklist

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

### Additional context

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

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

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

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

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

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

Close #4091

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

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

Close #4077

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

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

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 853841124
2026-01-08 12:22:45 -08:00
Joseph Pagadora 8afb99a078 feat: Support per-eval case and per-invocation rubrics in rubric-based evaluators
Co-authored-by: Joseph Pagadora <jcpagadora@google.com>
PiperOrigin-RevId: 853820099
2026-01-08 11:26:06 -08:00
Liang Wu 688791396a chore: Bumps version to v1.22.0 and updates CHANGELOG.md
Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 853816883
2026-01-08 11:18:10 -08:00
1119 changed files with 13914 additions and 2105 deletions
+2 -2
View File
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -96,7 +96,7 @@ jobs:
echo ""
set +e
FILES_WITH_FORBIDDEN_IMPORT=$(grep -lE '^from.*cli.*import.*$' $CHANGED_FILES)
FILES_WITH_FORBIDDEN_IMPORT=$(grep -lE '^from.*\bcli\b.*import.*$' $CHANGED_FILES)
GREP_EXIT_CODE=$?
set -e
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+2 -1
View File
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ on:
jobs:
audit-stale-issues:
if: github.repository == 'google/adk-python'
runs-on: ubuntu-latest
timeout-minutes: 60
+5 -3
View File
@@ -15,9 +15,11 @@ jobs:
# - New issues (need component labeling)
# - Issues labeled with "planned" (need owner assignment)
if: >-
github.event_name == 'schedule' ||
github.event.action == 'opened' ||
github.event.label.name == 'planned'
github.repository == 'google/adk-python' && (
github.event_name == 'schedule' ||
github.event.action == 'opened' ||
github.event.label.name == 'planned'
)
permissions:
issues: write
contents: read
@@ -9,6 +9,7 @@ on:
jobs:
upload-adk-docs-to-vertex-ai-search:
if: github.repository == 'google/adk-python'
runs-on: ubuntu-latest
steps:
+2 -2
View File
@@ -24,7 +24,7 @@ agentic architectures that range from simple tasks to complex workflows.
interacts with various services like session management, artifact storage,
and memory, and integrates with application-wide plugins. The runner
provides different execution modes: `run_async` for asynchronous execution
in production, `run_live` for bi-directional streaming interaction, and
in production, `run_live` for bidirectional streaming interaction, and
`run` for synchronous execution suitable for local testing and debugging. At
the end of each invocation, it can perform event compaction to manage
session history size.
@@ -316,7 +316,7 @@ navigation and refactoring.
immediately after the license header, before any other imports.
```python
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+172 -2
View File
@@ -1,5 +1,175 @@
# Changelog
## [1.23.0](https://github.com/google/adk-python/compare/v1.22.1...v1.23.0) (2026-01-22)
### ⚠ BREAKING CHANGES
* Breaking: Use OpenTelemetry for BigQuery plugin tracing, replacing custom `ContextVar` implementation ([ab89d12](https://github.com/google/adk-python/commit/ab89d1283430041afb303834749869e9ee331721))
* Add support to automatically create a session if one does not exist ([8e69a58](https://github.com/google/adk-python/commit/8e69a58df4eadeccbb100b7264bb518a46b61fd7))
### Features
* **[Core]**
* 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))
* **[Integrations]**
* Enhance `TraceManager` asynchronous safety, enrich BigQuery plugin logging, and fix serialization ([a4116a6](https://github.com/google/adk-python/commit/a4116a6cbfadc161982af5dabd55a711d79348b7))
* **[Live]**
* 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))
## [1.22.1](https://github.com/google/adk-python/compare/v1.22.0...v1.22.1) (2026-01-09)
### Bug Fixes
* Add back `adk migrate session` CLI ([8fb2be2](https://github.com/google/adk-python/commit/8fb2be216f11dabe7fa361a0402e5e6316878ad8)).
* Escape database reserved keyword ([94d48fc](https://github.com/google/adk-python/commit/94d48fce32a1f07cef967d50e82f2b1975b4abd9)).
## [1.22.0](https://github.com/google/adk-python/compare/v1.21.0...v1.22.0) (2026-01-08)
### Features
* **[Core]**
* 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)).
* **[Tools]**
* Expose mcps streamable http custom httpx factory parameter ([bfed19c](https://github.com/google/adk-python/commit/bfed19cd78298fc9f896da8ed82a756004e92094)).
* 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)).
* Harden YAML builder tmp save/cleanup([6f259f0](https://github.com/google/adk-python/commit/6f259f08b3c45ad6050b8a93c9bd85913451ece6)).
* 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)).
## [1.21.0](https://github.com/google/adk-python/compare/v1.20.0...v1.21.0) (2025-12-11)
### Features
@@ -444,7 +614,7 @@
* 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 follow up 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))
* Fix VertexAiSessionService base_url override to preserve initialized http_options ([8110e41](https://github.com/google/adk-python/commit/8110e41b36cceddb8b92ba17cffaacf701706b36), [c51ea0b](https://github.com/google/adk-python/commit/c51ea0b52e63de8e43d3dccb24f9d20987784aa5))
* Handle `App` instances returned by `agent_loader.load_agent` ([847df16](https://github.com/google/adk-python/commit/847df1638cbf1686aa43e8e094121d4e23e40245))
@@ -611,7 +781,7 @@
* AgentTool returns last content, instead of the content in the last event [bcf0dda](https://github.com/google/adk-python/commit/bcf0dda8bcc221974098f3077007c9e84c63021a)
* Fix adk deploy docker file permission [ad81aa5](https://github.com/google/adk-python/commit/ad81aa54de1f38df580915b7f47834ea8e5f1004)
* 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 self contained [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)
+1 -1
View File
@@ -1,5 +1,5 @@
#!/bin/bash
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.

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