Skip to content

chore: sync main -> v2#5630

Open
Jacksunwei wants to merge 337 commits into
v2from
main
Open

chore: sync main -> v2#5630
Jacksunwei wants to merge 337 commits into
v2from
main

Conversation

@Jacksunwei
Copy link
Copy Markdown
Collaborator

Automated sync of v1 changes from main into v2. The oncall is responsible for reviewing and merging this PR. Resolve conflicts in favor of the v2 implementation.

GWeale and others added 30 commits March 26, 2026 15:28
…definitions

The list_agents method in AgentLoader no longer attempts to determine the agent language for each directory

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 890078066
Merge #5016

Syncs version bump and CHANGELOG from release v1.28.0 to main.

COPYBARA_INTEGRATE_REVIEW=#5016 from google:release/v1.28.0 4e05efb
PiperOrigin-RevId: 890122693
…r session management

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 890127075
The workflow now accepts a `release_branch` input, checks out the specified release branch, and updates the version in `src/google/adk/version.py`

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 890134954
…ponses

Close: #4609

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 890144644
When an MCP server (or any toolset) is unavailable or raises an
exception during get_tools(), the error previously propagated uncaught
through _convert_tool_union_to_tools() and canonical_tools(), crashing
the entire agent silently with no log output.

This change wraps the toolset.get_tools_with_prefix() call in a
try-except that catches exceptions, logs a warning with the toolset
class name and error details, and returns an empty tool list. This
allows the agent to continue operating with tools from other working
toolsets.

The fix preserves the existing retry behavior — McpToolset's
@retry_on_errors decorator still attempts reconnection before the
error reaches this handler. On subsequent agent invocations,
get_tools() is called again, naturally retrying the connection.

Fixes: #3341

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 890512146
The deep_merge_dicts function will now extend lists when merging dictionaries, instead of overwriting them.

Co-authored-by: Vishwa Murugan <vishwamurugan@google.com>
PiperOrigin-RevId: 890531331
… ExpressMode and GCP projects

Otherwise we get errors of the form: `Project/location and API key are mutually exclusive in the client initializer` (https://github.com/googleapis/python-genai/blob/1ccad7b70ae1068cb5f3e866ad7ca4d42aa55e1e/google/genai/_api_client.py#L590-L591).

Co-authored-by: Yeesian Ng <ysian@google.com>
PiperOrigin-RevId: 890588927
PiperOrigin-RevId: 890595289
This PR updates the `toolbox-adk` package version in the `pyproject.toml` and also updates the MCP Toolbox server version to the latest in the docs.

PiperOrigin-RevId: 890633573
…ecution

This change introduces a new EnvironmentToolset within the ADK, providing tools to interact with a BaseEnvironment. The toolset includes Execute, ReadFile, EditFile, WriteFile. System instructions are injected to guide the LLM on workspace usage and file manipulation.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 890672569
…le I/O locally

This change introduces the LocalEnvironment class, which allows agents to execute shell commands and perform file operations using asyncio subprocesses on the local machine. It includes support for a working directory and custom environment variables. A sample agent configuration is also added to demonstrate its usage.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 890685517
Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 890694124
Merge #4842

### Link to Issue or Description of Change
**1. Link to an existing issue**

Closes #4841

**2. Changes**
This change aligns SSE transport behavior with Streamable HTTP transport for MCP tools, enabling users to customize the httpx.AsyncClient for SSE-based MCP connections (e.g., proxy, auth, TLS config).

- Update `SseConnectionParams` model to include httpx_client_factory parameter (matching StreamableHTTPConnectionParams pattern)
- Pass `httpx_client_factory` from `SseConnectionParams` to underlying `sse_client()` call
- Add `model_config` to `SseConnectionParams` to allow arbitrary types for the factory function
- Update docstrings to document the new `httpx_client_factory attribute`
- Add unit test for new senarios

### Testing Plan

**Unit Tests:**

- [x] I have added or updated unit tests for my change.
    - `tests/unittests/tools/mcp_tool/test_mcp_session_manager.py`
- [x] All unit tests pass locally.
    - All test cases have passed the test.

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

1. Set custom httpx_client_factory parameter for SseConnectionParams
```Python
from typing import Any

import httpx
from google.adk.agents.llm_agent import Agent
from google.adk.models import LiteLlm
from google.adk.tools.mcp_tool import SseConnectionParams, McpToolset

# Cutom httpx client factory for MCP SSE transport
def custom_httpx_client_factory(
    headers: dict[str, str] | None = None,
    timeout: httpx.Timeout | None = None,
    auth: httpx.Auth | None = None,
) -> httpx.AsyncClient:
    # Print message for debugging
    print(' === Custom httpx_client_factory running! ===')
    kwargs: dict[str, Any] = {
        "follow_redirects": True,
    }
    if timeout is None:
        kwargs["timeout"] = httpx.Timeout(30, read=300)
    else:
        kwargs["timeout"] = timeout
    if headers is not None:
        kwargs["headers"] = headers
    if auth is not None:
        kwargs["auth"] = auth
    return httpx.AsyncClient(**kwargs)

connection_params = SseConnectionParams(
    url='http://127.0.0.1:9000/sse',
    httpx_client_factory=custom_httpx_client_factory, # Custom httpx client factory
)

tool = McpToolset(connection_params=connection_params)

root_agent = Agent(
    model=LiteLlm(model="ollama_chat/qwen3.5:35b-a3b-q4_K_M"),
    name='root_agent',
    description='A helpful assistant for user questions.',
    instruction='Answer user questions to the best of your knowledge',
    tools=[tool],
)
```

2.  Run the Agent, and display the debug log in console
```
2026-03-15 23:54:14,304 - INFO - agent_loader.py:130 - Found root_agent in my_agent.agent
INFO:     127.0.0.1:55642 - "POST /run_sse HTTP/1.1" 200 OK
 === Custom httpx_client_factory running! ===
2026-03-15 23:54:14,345 - INFO - _client.py:1740 - HTTP Request: GET http://127.0.0.1:9000/sse "HTTP/1.1 200 OK"
2026-03-15 23:54:14,349 - INFO - _client.py:1740 - HTTP Request: POST http://127.0.0.1:9000/messages/?session_id=b5750c6e214048c28110dff11c412ecb "HTTP/1.1 202 Accepted"
```

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

Co-authored-by: Kathy Wu <wukathy@google.com>
COPYBARA_INTEGRATE_REVIEW=#4842 from ushelp:main e3125fb
PiperOrigin-RevId: 890708694
- Add 1P BQ Skills  `bigquery-ai-ml`, add mandatory reference routing and reference file for `AI.*` syntax.
- Include dedicated reference documents for various BigQuery ML features.
- Update unit tests to fully assert skill validations.

Co-authored-by: Haiyuan Cao <haiyuan@google.com>
PiperOrigin-RevId: 890749300
Revert global list extension in deep_merge_dicts and instead explicitly handle list extension only for render_ui_widgets in merge_parallel_function_response_events.

Co-authored-by: Vishwa Murugan <vishwamurugan@google.com>
PiperOrigin-RevId: 891147765
Close: #4671

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 891827874
…n intermediate data

PiperOrigin-RevId: 891846041
This reduces latency by avoiding redudant network calls

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 891931454
Moved `before_model_callback` inside the `call_llm` span.
Wrapped both `after_model_callback` and error callbacks with `trace.use_span()` to bind callbacks to the correct overarching span.
Added regression tests to verify span ID consistency.

Co-authored-by: Haiyuan Cao <haiyuan@google.com>
PiperOrigin-RevId: 891952170
Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 891960308
Fixes an issue where the Agent Analytics plugin could log plain-text
OAuth credentials and access tokens to BigQuery. Sensitive keys are
now redacted.

Co-authored-by: Haiyuan Cao <haiyuan@google.com>
PiperOrigin-RevId: 891963630
…into an isolated snapshot sequence before starting loop

_list_sessions_impl intermittently would throw `RuntimeError: dictionary changed size during iteration`

Co-authored-by: Ankur Sharma <ankusharma@google.com>
PiperOrigin-RevId: 892454902
PiperOrigin-RevId: 892466615
This change updates the method used for sending text, audio and video data to the model.

Closes issue #5018

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 893174037
The `receive` method now accumulates function calls from multiple `LiveServerMessage` instances. These accumulated tool calls are yielded as a single `LlmResponse` containing all function call parts only when a turn_complete message is received.

Without the change, the tool_1's response is sent to the model as soon as it's generated, triggering a second call for tool_2. Upon receiving two consecutive tool_2's responses, the model utters the same message twice.
Fixes issue #4902

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 893197482
…manager package

Reasons for moving `SecretManagerClient`:

1. **Logical Grouping**: `SecretManagerClient` represents an integration with Google Cloud Secret Manager. Placing it in the `integrations` package is more intuitive and organized than keeping it within a specific tool's client directory.

2. **Increased Reusability**: As a common utility in `google.adk.integrations`, it is now easily discoverable and accessible for any other agent or tool in the ADK that needs to interact with Google Cloud Secret Manager.

3. **Better Abstraction**: It provides a clean, simplified interface for secret retrieval from Google Cloud Secret Manager. Future enhancements will be consolidated in the same package.

4. **Cleaner Tooling**: The `apihub_tool` can now focus purely on the API Hub logic while delegating secret management to this dedicated package.

For what its worth, `SecretManagerClient` is not used by the `apihub_tool` at the moment.

PiperOrigin-RevId: 893221472
wukath and others added 30 commits May 5, 2026 11:49
…ent engine

Deploying using API key has been leading to "Deploy failed: 'NoneType' object has no attribute 'before_request'" errors because creating cloud resources requires ADC credentials (project id and region)

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 910821145
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 910839657
… available

This reduces the token usage of having skills appended to the instruction on every call

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 910904229
…istered AuthProvider

PiperOrigin-RevId: 911115744
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 911411431
Merge #5612

## Summary
- Added `.github/header-checker-lint.yml` with full configuration to ignore `src/google/adk/cli/browser/**`.
- Ensured Python files are still checked by adding `py` to `sourceFileExtensions`

## Test Plan
- Verify that the `License Header Lint GCF` / `header-check` status check passes on this PR

Co-authored-by: Wei Sun (Jack) <weisun@google.com>
COPYBARA_INTEGRATE_REVIEW=#5612 from google:ci/ignore-browser-assets d08d161
PiperOrigin-RevId: 911583387
Co-authored-by: Wei Sun (Jack) <weisun@google.com>
PiperOrigin-RevId: 911737937
…s empty response

PiperOrigin-RevId: 911999966
PiperOrigin-RevId: 912057968
Express mode API was updated to require "get_default_api_key: True" for returning api key

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 912153767
…ssion

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 912249311
Generates a random code verifier and code challenge during the initial auth request. During token exchange, the client sends the original code verifier so the server can verify it matches the previously sent challenge. This prevents attacks by ensuring that only the client that initiated the request can obtain the final access token.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 912703679
The analyzer crashed on `sum([None, ...])` whenever any event had
fingerprint-only cache metadata (cache_name=None, invocations_used=None),
which happens on every session's first turn. Also fixes `cache_refreshes`
over-counting None as a unique cache instance.

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 912722966
Merge #5648

Syncs version bump and CHANGELOG from release v1.33.0 to main.

COPYBARA_INTEGRATE_REVIEW=#5648 from google:release/v1.33.0 643ebd1
PiperOrigin-RevId: 912728912
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 912743254
…ded on by extension developers

PiperOrigin-RevId: 912771457
…mple

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 913789974
- Clean up the unused private _ProtocolType import

Co-authored-by: Sasha Sobran <asobran@google.com>
PiperOrigin-RevId: 913817935
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 913891628
Merge #5350
Fixes #5329

Co-authored-by: Xuan Yang <xygoogle@google.com>
COPYBARA_INTEGRATE_REVIEW=#5350 from voidborne-d:fix/persist-refreshed-oauth2-credential 0ef3d8c
PiperOrigin-RevId: 913922074
…andle from parent live agent to avoid interrupting the conversation

PiperOrigin-RevId: 914367901
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 914400439
Merge #5597

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

- Related: #4971

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

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

**Problem:**
A2A support lacked pluggable or persistent task store backends, forcing a strict default to `InMemoryTaskStore`.

**Solution:**
Extended `ServiceRegistry` and `ServiceFactory` to support URI-driven configuration for A2A task stores. Added built-in support for `memory://`, `postgresql://`, `mysql://`, and `sqlite://` schemes. Plumbed the options down into `to_a2a()` and `get_fast_api_app()`, ensuring connection strings are securely redacted from application logs.

### Testing Plan

**Unit Tests:**

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

Summary: Ran `pytest` against `test_agent_to_a2a.py`, `test_fast_api.py`, `test_service_registry.py`, and `test_service_factory.py`. All 131 unit tests passed successfully.

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

Compiled the package distribution wheel via `uv build` and successfully validated its installation inside a clean isolated sandbox environment via `uv pip install dist/google_adk-1.32.0-py3-none-any.whl[a2a]`. Verified that the application instantiates default in-memory stores and custom persistent URI stores

### Checklist

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

COPYBARA_INTEGRATE_REVIEW=#5597 from allen-stephen:feat/a2a-task-store-support f53ba0f
PiperOrigin-RevId: 914496800
Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 914515552
…sume

When resuming a session with Anthropic (Claude) models, tool_use IDs were
getting stripped during content replay, causing BadRequestError from the
Anthropic API. Two fixes: (1) preserve function call IDs in the contents
flow for AnthropicLlm models, (2) sanitize invalid/empty tool_use IDs
to match Anthropic's required pattern (^[a-zA-Z0-9_-]+$) instead of
passing empty strings.

Fixes #5074

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 914550905
Merge #5679

Same config as in adk-python-community

COPYBARA_INTEGRATE_REVIEW=#5679 from DeanChensj:main d33c368
PiperOrigin-RevId: 914634367
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.