Compare commits

..

78 Commits

Author SHA1 Message Date
Yasir Modak 7e00c52074 Update bug_report.md 2026-01-22 12:40:37 -08:00
Yasir Modak 58204fb421 Merge branch 'main' into ymodak-patch-1 2026-01-21 19:32:46 -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
Yasir Modak 565a0e1ecb Merge branch 'main' into ymodak-patch-1 2026-01-21 14:05:11 -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
Yasir Modak 49da199c02 Update .github/ISSUE_TEMPLATE/bug_report.md
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-01-20 13:27:59 -08:00
Yasir Modak 88a246f308 Update .github/ISSUE_TEMPLATE/bug_report.md
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-01-20 13:27:45 -08:00
Yasir Modak fd46b7a66b Update bug_report.md 2026-01-20 13:25:16 -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
1111 changed files with 8852 additions and 1901 deletions
+32 -17
View File
@@ -7,34 +7,49 @@ assignees: ''
---
** Please make sure you read the contribution guide and file the issues in the right place. **
[Contribution guide.](https://google.github.io/adk-docs/contributing-guide/)
## 🔴 Required Information
*Please ensure all items in this section are completed to allow for efficient triaging. Requests without complete information may be rejected / deprioritized. If an item is not applicable to you - please mark it as N/A*
**Describe the bug**
**Describe the Bug**
A clear and concise description of what the bug is.
**To Reproduce**
Please share a minimal code and data to reproduce your problem.
Steps to reproduce the behavior:
**Steps to Reproduce**
Please provide a numbered list of steps to reproduce the behavior:
1. Install '...'
2. Run '....'
3. Open '....'
4. Provide error or stacktrace
**Expected behavior**
**Expected Behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Observed Behavior**
What actually happened? Include error messages or crash stack traces here.
**Desktop (please complete the following information):**
- OS: [e.g. macOS, Linux, Windows]
- Python version(python -V):
- ADK version(pip show google-adk):
**Environment Details**
* **ADK Library Version:** (e.g., 2.0.1)
* **Desktop OS:** (e.g., macOS, Linux, Windows)
* **Python Version:**
**Model Information:**
- Are you using LiteLLM: Yes/No
- Which model is being used(e.g. gemini-2.5-pro)
**Model Information**
* **Are you using LiteLLM:** Yes/No
* **Which model is being used:** (e.g., gemini-2.5-pro)
**Additional context**
---
## 🟡 Optional Information
*Providing this information greatly speeds up the resolution process.*
**Regression**
Did this work in a previous version of ADK? If so, which one?
**Logs**
Please attach relevant logs. Wrap them in code blocks (```) or attach a text file.
```text
// Paste logs here
```
**Screenshots / Video**
If applicable, add screenshots or screen recordings to help explain your problem.
**Additional Context**
Add any other context about the problem here.
@@ -1,102 +0,0 @@
name: Breaking Change Detector
on:
pull_request:
branches:
- main
paths:
- 'src/**'
jobs:
check-api:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for accessing the main branch history
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install the latest version of uv
uses: astral-sh/setup-uv@v5
- name: Install dependencies
# Syncing installs the package and its dependencies (populating google.* namespace)
# Installing 'griffe' ensures the tool is available in the environment
run: |
uv sync --extra test
uv pip install griffe
- name: Run Breaking Change Detection
# Uses 'uv run python' to execute in the environment with all dependencies installed
run: |
uv run python - <<EOF
import sys
import griffe
from griffe import find_breaking_changes, load, load_git
def check_return_types(old_obj, new_obj):
"""Custom check to strictly compare return type annotations."""
errors = []
# Check Runner.run specifically, or extend to check all methods
try:
old_run = old_obj.members["Runner"].members["run"]
new_run = new_obj.members["Runner"].members["run"]
# Convert to string and strip to compare the annotation text
old_ret = str(old_run.returns).strip()
new_ret = str(new_run.returns).strip()
if old_ret != new_ret:
errors.append(
f"Breaking Change in {new_run.path}: Return type changed from '{old_ret}' to '{new_ret}'"
)
except KeyError:
pass # Member missing (will be caught by standard checks)
except AttributeError:
pass # Member might not be a function
return errors
try:
print("Loading new API (from local source)...")
# allow_inspection=False forces static analysis, preventing sys.modules caching issues
new_api = load("google.adk", search_paths=["src"], allow_inspection=False)
print("Loading baseline API (from main branch)...")
old_api = load_git("google.adk", ref="main", search_paths=["src"], allow_inspection=False)
print("Running detection...")
# 1. Standard Griffe Checks (Removals, Parameter changes)
breakages = list(find_breaking_changes(old_api, new_api))
# 2. Custom Return Type Checks (Workaround for Griffe limitation)
custom_errors = check_return_types(old_api, new_api)
found_issues = False
if breakages:
found_issues = True
print(f"::error::Found {len(breakages)} standard breaking changes!")
for breakage in breakages:
print(breakage.explain())
if custom_errors:
found_issues = True
print(f"::error::Found {len(custom_errors)} return type mismatches!")
for error in custom_errors:
print(f"- {error}")
if found_issues:
sys.exit(1)
print("Success: No breaking changes detected.")
except Exception as e:
print(f"::error::Breaking change detection failed: {e}")
sys.exit(1)
EOF
+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.
+2 -2
View File
@@ -531,7 +531,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))
@@ -698,7 +698,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.

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