This change enables the LiteLLM adapter to correctly parse and generate Anthropic's structured "thinking_blocks" format, which includes a "signature" for each thought block. The "signature" is crucial for Anthropic models to maintain their reasoning state across multiple turns, particularly when tool calls are made
Close#4801
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 885131757
The Vertex AI session service does not natively support persisting usage_metadata. This change serializes usage_metadata into the custom_metadata field under the key '_usage_metadata' when appending events and deserializes it back when retrieving events. This allows usage information to be round-tripped through the Vertex AI session service.
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 885121070
This change introduces a new `SpannerAdminToolset` with tools for managing Google Cloud Spanner resources. The toolset includes functions to list and get details of Spanner instances and instance configurations, and to create, list databases. The new toolset is marked as experimental. Unit tests for the new admin tools are also added
PiperOrigin-RevId: 885116111
The previous test for unmapped LiteLLM finish_reason values was ineffective because LiteLLM's internal models normalize certain values (e.g., "eos" to "stop") before ADK processes them
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 884678119
Merge https://github.com/google/adk-python/pull/4818
**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:**
`src/google/adk/models/google_llm.py` includes a mitigation link for `429 RESOURCE_EXHAUSTED`, but the current URL points to a broken docs anchor:
https://google.github.io/adk-docs/agents/models/#error-code-429-resource_exhausted
<img width="1067" height="640" alt="image" src="https://github.com/user-attachments/assets/8aee07da-3007-4312-93d3-161321c01f2f" />
**Solution:**
Update the link to the current Gemini-specific docs page so users are directed to the correct troubleshooting section:
https://google.github.io/adk-docs/agents/models/google-gemini/#error-code-429-resource_exhausted
<img width="1161" height="732" alt="image" src="https://github.com/user-attachments/assets/1badf7ab-9411-4f56-a719-6ba2a61ca7ce" />
### Testing Plan
This is a small string-only fix for a broken documentation link.
No unit tests were added because there does not appear to be existing test coverage for this message and the change does not affect runtime behavior beyond the emitted URL.
**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:**
Confirmed the updated URL in the source points to the intended documentation page/anchor.
### Checklist
- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [ ] I have commented my code, particularly in hard-to-understand areas.
- [ ] I have added tests that prove my fix is effective or that my feature works.
- [ ] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [ ] Any dependent changes have been merged and published in downstream modules.
### Additional context
This change only updates the documentation URL shown in the `RESOURCE_EXHAUSTED` guidance message.
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4818 from ftnext:fix-429-doc-link 1c533453a9428a3fcc6d22b97d64834f0a4f3acb
PiperOrigin-RevId: 884581120
this sample can be used to test the latest gemini embedding model
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 884574396
When using OAuth2Session with `client_secret_post`, Authlib automatically includes the client_id and client_secret in the request body. Explicitly passing `client_id` again results in a duplicate parameter in the token exchange request, which can cause issues with some OAuth providers.
Close#4782
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 884574091
Tool use:
The class delegates the responsibility to Vertex Gen AI Eval SDK. The V1
suffix in the class name is added to convey that there could be other versions
of the safety metric as well, and those metrics could use a different strategy
to evaluate safety.
Task trajectory:
this metric is different from `Multi-Turn Overall Task Success`,
in the sense that task success only concerns itself with the goal of whether
the success was achieved or not. How that was achieved is not its concern.
This metric on the other hand does care about the path that agent took to
achieve the goal.
Co-authored-by: Ankur Sharma <ankusharma@google.com>
PiperOrigin-RevId: 884525532
The metric takes into account all the turns of the multi-turn conversation.
The class delegates the responsibility to Vertex Gen AI Eval SDK. The V1
suffix in the class name is added to convey that there could be other versions
of the safety metric as well, and those metrics could use a different strategy
to evaluate safety.
Co-authored-by: Ankur Sharma <ankusharma@google.com>
PiperOrigin-RevId: 884504910
The AgentEngineSandboxCodeExecutor now has three initialization modes:
1. Create both an Agent Engine and sandbox if neither resource name is provided.
2. Creating a new sandbox within a provided agent_engine_resource_name.
3. Using a provided sandbox_resource_name.
PiperOrigin-RevId: 884088248
The gemini-embedding-2-preview model requires the Vertex AI
:embedContent endpoint instead of the legacy :predict endpoint used
by older models (text-embedding-004, text-embedding-005).
In google-genai <1.64.0, embed_content() unconditionally routed to
:predict on Vertex AI, which returns FAILED_PRECONDITION for this
model.
v1.64.0 (googleapis/python-genai@af40cc6) introduced model-aware
dispatch in embed_content(): models with "gemini" in the name are
routed to :embedContent via t_is_vertex_embed_content_model(), while
older text-embedding-* models continue to use :predict.
This version also enforces a single-content-per-call limit for the
embedContent API, which is why FilesRetrieval sets embed_batch_size=1.
Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 883689438
Merge https://github.com/google/adk-python/pull/4718
### Link to Issue or Description of Change
**1. Link to an existing issue (if applicable):**
- Closes: N/A
- Related: N/A
**2. Or, if no issue exists, describe the change:**
**Problem**
ADK’s MCP integration currently does not expose the MCP sampling callback capability.
This prevents agent-side LLM sampling handlers from being used when interacting with MCP servers that support sampling.
The MCP Python SDK supports sampling callbacks, but these parameters are not propagated through the ADK MCP integration layers.
**Solution**
Add sampling callback support by propagating the parameters through the MCP stack:
- Add `sampling_callback` and `sampling_capabilities` parameters to `McpToolset`
- Forward them to `MCPSessionManager`
- Forward them to `SessionContext`
- Pass them into `ClientSession` initialization
This enables agent-side sampling handling when interacting with MCP servers.
---
### Testing Plan
**Unit Tests**
- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.
Added `test_mcp_sampling_callback.py` to verify that the sampling callback is correctly invoked.
Example result:
pytest tests/unittests/tools/mcp_tool/test_mcp_sampling_callback.py
1 passed
**Manual End-to-End (E2E) Tests**
Manual testing was performed using a FastMCP sampling example server where the sampling callback was invoked from the agent side and returned the expected response.
---
### Checklist
- [x] I have read the CONTRIBUTING.md document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code where necessary.
- [x] I have added tests proving the feature works.
- [x] Unit tests pass locally.
- [x] I have manually tested the change end-to-end.
---
### Additional context
This change aligns ADK MCP support with the sampling capabilities available in the MCP Python SDK and enables agent implementations to handle sampling requests via a callback.
Co-authored-by: Kathy Wu <wukathy@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4718 from Piyushmrya:fix-mcp-sampling-callback 18f477f04ad357d698b0a4c8a4392936b9f6d185
PiperOrigin-RevId: 883401178
This change introduces a new interceptor that adds the 'https://google.github.io/adk-docs/a2a/a2a-extension/' extension to the request headers in the A2A client from the RemoteAgent side. To send this extension along with requests, the RemoteAgent has to be instantiated with the `use_legacy` flag set to False. The AgentExecutor will default to the new implementation when this extension is requested by the client, but this behavior can be disabled via the `use_legacy` flag.
The 'force_new' flag on the agent_executor side can be used to bypass the presence of the extension, and always activate the new version of the agent_executor.
PiperOrigin-RevId: 883021792
The `can_use_output_schema_with_tools` function now checks if a model is a LiteLlm instance by inspecting its type's Method Resolution Order, rather than directly importing `LiteLlm`
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 882253446
This change adds logic to extract and re-embed the `thought_signature` field associated with function calls in Gemini models when converting between LiteLLM's ChatCompletionMessageToolCall and ADK's types.Part
Close#4650
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 882212223
The _update_type_string function now recursively processes "properties" at any level of the schema, ensuring that all "type" fields within nested objects are correctly lowercased. This improves handling of complex
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 882050939
The flow for integrating a new auth method will be as follows. The ADK framework contributor will
1. extend the `AuthScheme` to create their own within `adk/auth/auth_scheme.py`
2. implement `BaseAuthProvider` within their dedicated directory in `adk/integrations/auth`
3. do the static registration of the new scheme and provider with AuthProviderRegistry of CredentialManager.
PiperOrigin-RevId: 881775983
The classes `BaseSamplingResult` and `BaseAgentWithScores` are renamed to `SamplingResult` and `AgentWithScores`, respectively. The corresponding TypeVars are renamed to `SamplingResultT` and `AgentWithScoresT` to avoid naming conflicts. Imports across ADK are updated to reflect these changes.
These changes were made to better align with the naming philosophy of ADK.
Co-authored-by: Keyur Joshi <keyurj@google.com>
PiperOrigin-RevId: 881635593
**1. Link to an existing issue (if applicable):**
- Closes: #_issue_number_
- Related: #_issue_number_
**2. Or, if no issue exists, describe the change:**
**Problem:**
- Currently, the ADK doesn't expose telemetry for reasoning tokens limit, reasoning tokens and system instruction tokens.
- In addition to this, the OpenTelemetry semantic conventions for Generative AI do not yet formally include usage fields for `reasoning_tokens_limit`, `reasoning_tokens`, and `system_instruction_tokens`.
- Setting these natively under the standard `gen_ai.usage.*` namespace risks colliding with future official OTel specifications if determining the structure or naming changes prior to stabilization.
**Solution:**
Namespace these telemetry attributes as experimental by adding the `experimental.` prefix to their keys in telemetry/tracing.py.
(For example, changing them to `gen_ai.usage.experimental.reasoning_tokens`).
This safely scopes these usage metrics until they are officially standardized by the OTel community.
### Testing Plan
**Unit Tests:**
- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.
_Please include a summary of passed `pytest` results._
All existing tests across `google-adk` pass correctly.
**Manual End-to-End (E2E) Tests:**
N/A - This is purely a key rename for OpenTelemetry exports and does not negatively impact functional framework logic.
### 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
None
Co-authored-by: Achuth Narayan Rajagopal <achuthr@google.com>
PiperOrigin-RevId: 881568099
This change updates the LiteLLM integration to correctly process responses with a "length" finish reason. Specifically, it:
- Maps "length" to types.FinishReason.MAX_TOKENS.
- Checks for truncated JSON arguments within tool calls when the finish reason is "length" and reports an error if parsing fails.
Close#4482
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 881514246
Merge https://github.com/google/adk-python/pull/4693
### Link to Issue or Description of Change
**1. Link to an existing issue:**
- Closes: #4673
- Related: #3562, PR #3662
**Problem:**
When `EventsCompactionConfig` is configured on an `App`, the compaction mechanism correctly summarizes old events, but `Runner._get_or_create_session` still calls `get_session()` **without any `GetSessionConfig`**, loading the **full event history** on every invocation.
This means compaction only reduces the LLM context window — it does nothing to reduce the session loading overhead. As reported in #4673, real-world sessions with ~4,800 events take 70+ seconds to load via `get_session` even though compaction summaries exist.
**Solution:**
Add a `get_session_config` field to `RunConfig` and thread it through all Runner entry points so the session service can filter events during loading:
- **`RunConfig.get_session_config`**: New optional `GetSessionConfig` field that users can set to control `num_recent_events` or `after_timestamp`.
- **`_get_or_create_session`**: Updated to accept and forward `get_session_config` to `session_service.get_session()`.
- **All entry points updated**: `run_async`, `run_live`, `rewind_async`, and `run_debug` all pass the config through.
This subsumes the approach in stale PR #3662 (open since Dec 2025 with unaddressed review feedback) while also addressing the reviewer's requested changes (pass config in `rewind_async`, initialize in `run_debug`, add comprehensive tests).
**Usage:**
```python
from google.adk.agents.run_config import RunConfig
from google.adk.sessions.base_session_service import GetSessionConfig
# Only load the 50 most recent events — sufficient when compaction is active
run_config = RunConfig(
get_session_config=GetSessionConfig(num_recent_events=50),
)
async for event in runner.run_async(
user_id=user_id,
session_id=session_id,
new_message=message,
run_config=run_config,
):
...
```
### Testing Plan
**Unit Tests:**
- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.
5 new tests added covering all entry points:
- `test_run_async_passes_get_session_config` — verifies `run_async` forwards config
- `test_run_live_passes_get_session_config` — verifies `run_live` forwards config
- `test_rewind_async_passes_get_session_config` — verifies `rewind_async` forwards config
- `test_run_debug_passes_get_session_config` — verifies `run_debug` forwards config
- `test_get_session_config_limits_events` — verifies `InMemorySessionService` actually limits events
```
======================= 39 passed, 10 warnings in 2.44s ========================
```
### 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] Any dependent changes have been merged and published in downstream modules.
### Additional context
This is the minimal viable fix — it gives users explicit control over session loading. A follow-up enhancement could automatically derive `GetSessionConfig` from `EventsCompactionConfig` (e.g., only load events after the last compaction timestamp), but that requires additional design decisions about the feedback loop between compaction and session loading.
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4693 from OiPunk:codex/adk-python-4673-get-session-config 85a814e679095c9fb20e4389320b51972bde6ce1
PiperOrigin-RevId: 881479524
Link to Issue or Description of Change
1. Link to an existing issue (if applicable):
Closes: #issue_number
Related: #issue_number
2. Or, if no issue exists, describe the change:
Problem:
The agent's specific version wasn't being tracked in our telemetry data, limiting our ability to trace issues to specific agent versions. This change introduces the gen_ai.agent.version attribute to span context, defaulting to an empty string if omitted for backwards compatibility.
Solution:
We want to capture the specific version of an agent during execution by adding an optional version field to the base agent configurations (BaseAgent, BaseAgentConfig).
This solution was chosen because exposing this field directly to OpenTelemetry span attributes (gen_ai.agent.version) ensures the version is automatically recorded alongside other existing metadata (like name and description) during invocation. Defaulting the value to an empty string ensures backwards compatibility without breaking existing agent implementations that do not specify a version.
Testing Plan
- Added test_trace_agent_invocation_with_version to verify that the gen_ai.agent.version attribute is correctly captured when agent.version is populated.
- Updated existing telemetry span tests to ensure gen_ai.agent.version safely defaults to an empty string ('') when no version is provided.
Unit Tests:
- I have added or updated unit tests for my change.
- All unit tests pass locally.
Manual End-to-End (E2E) Tests:
- Tested on Agent Engine and in a local deployment.
Checklist
[x] I have read the CONTRIBUTING.md document.
[x] I have performed a self-review of my own code.
[x] I have commented my code, particularly in hard-to-understand areas.
[x] I have added tests that prove my fix is effective or that my feature works.
[x] New and existing unit tests pass locally with my changes.
[x] I have manually tested my changes end-to-end.
[x] Any dependent changes have been merged and published in downstream modules.
Additional context
Add any other context or screenshots about the feature request here.
Co-authored-by: Achuth Narayan Rajagopal <achuthr@google.com>
PiperOrigin-RevId: 881234134