[pull] main from google:main#393
Merged
Merged
Conversation
PiperOrigin-RevId: 941154780
Merge #5516 ## Summary Fixes #5469. When `output_schema` is a raw dict (e.g. `{"type": "object", "properties": {...}}`), `SetModelResponseTool.__init__` previously fell through to the generic `else` branch and used the dict **instance** as the parameter annotation. Downstream, `_function_parameter_parse_util._is_builtin_primitive_or_compound` does `annotation in _py_builtin_type_to_schema_type.keys()`, which calls `__hash__` on the annotation and raises `TypeError: unhashable type: 'dict'`. This change adds an explicit `elif isinstance(output_schema, dict)` branch that uses the `dict` type (hashable) as the annotation, so the existing builtin lookup maps it to `Type.OBJECT` cleanly. `run_async` already handles this case via the existing `args.get('response')` pass-through. ## Reproduction (before fix) ```python from google.adk.agents import Agent agent = Agent( name="test", model="gemini-2.5-flash", instruction="You are a helpful agent.", output_schema={"type": "object", "properties": {"result": {"type": "string"}}}, ) # -> TypeError: unhashable type: 'dict' ``` ## Testing plan - Added regression unit tests in `tests/unittests/tools/test_set_model_response_tool.py`: - `test_tool_initialization_raw_dict_schema` — `__init__` with a raw dict does not crash and stores the schema. - `test_function_signature_generation_raw_dict_schema` — generated signature has a single `response: dict` parameter (annotation is the `dict` type, not the dict instance). - `test_get_declaration_raw_dict_schema` — `_get_declaration()` returns a valid declaration without raising `TypeError`. - `test_run_async_raw_dict_schema` — `run_async` returns the response unchanged. - Run: `pytest tests/unittests/tools/test_set_model_response_tool.py -q` - Existing tests for `BaseModel`, `list[BaseModel]`, `list[str]`, `dict[str, int]` schemas remain unchanged and still pass. ## Notes - Schema fidelity (propagating dict-schema constraints into the function declaration) is intentionally out of scope; this PR only fixes the crash, matching the issue's reported scope and the existing handling for `list[str]` / `dict[str, int]`. Co-authored-by: Xuan Yang <xygoogle@google.com> COPYBARA_INTEGRATE_REVIEW=#5516 from MukundaKatta:fix/set-model-response-tool-dict-schema 5e808a9 PiperOrigin-RevId: 941169611
Move graph validation and parsing logic from `_graph.py` to dedicated utility modules (`_graph_validation.py` and `_graph_parser.py`) under `workflow/utils/`. This simplifies the core `Graph` and `Edge` model definitions. Co-authored-by: Shangjie Chen <deanchen@google.com> PiperOrigin-RevId: 941176423
- Remove unused local variable `target_state` in `_workflow.py`. - Remove unused `ctx` argument from `NodeRunner._attempt_retry`. - Remove unused `node_path` and `curr_parent_ctx` arguments from `check_interception` utility function. Co-authored-by: Shangjie Chen <deanchen@google.com> PiperOrigin-RevId: 941198065
Merge #6128 …ection Expose a parameterized query tool execute_sql_parameterized that automatically maps and injects secure parameters (like user_id) from the tool context to Bigtable's view_parameters. **Please ensure you have read the [contribution guide](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) before creating a pull request.** ### Link to Issue or Description of Change **1. Link to an existing issue (if applicable):** - Closes: #_issue_number_ - Related: #_issue_number_ **2. Or, if no issue exists, describe the change:** _If applicable, please follow the issue templates to provide as much detail as possible._ **Problem:** _A clear and concise description of what the problem is._ **Solution:** _A clear and concise description of what you want to happen and why you choose this solution._ ### Testing Plan _Please describe the tests that you ran to verify your changes. This is required for all PRs that are not small documentation or typo fixes._ **Unit Tests:** - [ ] 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 - [ ] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document. - [ ] 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. - [ ] I have manually tested my changes end-to-end. - [ ] Any dependent changes have been merged and published in downstream modules. ### Additional context _Add any other context or screenshots about the feature request here._ COPYBARA_INTEGRATE_REVIEW=#6128 from ad548:feat/bigtable-parameterized-views f5902fd PiperOrigin-RevId: 941207338
Merge #5692 ### Link to Issue or Description of Change **1. Link to an existing issue (if applicable):** - Closes: #5691 This change adds `auth_credential.oauth2.redirect_uri = None` to the OAuth2 strip block at the three call sites where credential hashing happens. `redirect_uri` is deployment configuration (which callback URL the auth server should redirect to), not part of the credential identity, so it should be excluded from the hash just as access_token, refresh_token, expires_at, and the other transient OAuth2 fields already are. Without this change, a credential minted under one deployment URL cannot be retrieved when the deployment moves to another. ### Testing Plan **Unit Tests:** - [x] I have added or updated unit tests for my change. - [x] All unit tests pass locally. Three new tests, one per affected method. Each constructs two `AuthCredential` instances that differ only in `redirect_uri` and asserts the computed key is identical: - `tests/unittests/tools/openapi_tool/openapi_spec_parser/test_tool_auth_handler.py::test_credential_key_is_stable_across_redirect_uri` - `tests/unittests/tools/openapi_tool/openapi_spec_parser/test_tool_auth_handler.py::test_legacy_credential_key_is_stable_across_redirect_uri` - `tests/unittests/auth/test_auth_config.py::test_credential_key_is_stable_across_redirect_uri` ``` $ pytest tests/unittests/tools/openapi_tool/openapi_spec_parser/test_tool_auth_handler.py tests/unittests/auth/test_auth_config.py ======================== 14 passed, 8 warnings in 2.90s ======================== $ pytest tests/unittests/ ================ 5740 passed, 2340 warnings in 86.64s (0:01:26) ================ ``` **Manual End-to-End (E2E) Tests:** A self-contained Runner-based reproduction is at https://github.com/doughayden/adk-issue-examples/tree/main/05-redirect_uri_in_credential_hash. The agent definition (`agent.py`) wires up an `OpenAPIToolset` against a local OAuth2 test server, configured with one redirect_uri value. `main.py` constructs an `InMemoryRunner`, seeds a real (non-expired) OAuth2 credential into session state under a different redirect_uri's hash, and runs the agent. The `--apply-fix` flag monkey-patches the proposed fix to demonstrate the resolution end-to-end. Without the fix: ``` 🌤️ WeatherAssistant Agent — redirect_uri-in-hash repro ============================================================ Proposed fix applied: False STORED_REDIRECT_URI: http://localhost:8080/callback CURRENT_REDIRECT_URI: http://localhost:8081/callback Hash keys produced by ToolContextCredentialStore.get_credential_key: STORED → oauth2_55f666541ad22e39_oauth2_8ba0457897522d9d_existing_exchanged_credential CURRENT → oauth2_55f666541ad22e39_oauth2_ae16199243c358df_existing_exchanged_credential ❌ Keys differ — credentials minted under STORED are not retrievable. 👤 User: What's the weather in San Francisco? 🌤️ Weather Assistant event stream: [function_call] get_weather by WeatherAssistant [auth_event] adk_request_credential by WeatherAssistant [function_response] get_weather by WeatherAssistant [text] WeatherAssistant: 'It seems I need your authorization to access weather data. Could you please g...' Event counts: function_calls: 1 auth_events: 1 function_responses: 1 text_events: 1 ✅ Bug reproduced: agent emitted 1 adk_request_credential event(s) despite a valid seeded credential being present in state. ``` With the fix: ``` 🌤️ WeatherAssistant Agent — redirect_uri-in-hash repro ============================================================ Proposed fix applied: True STORED_REDIRECT_URI: http://localhost:8080/callback CURRENT_REDIRECT_URI: http://localhost:8081/callback Hash keys produced by ToolContextCredentialStore.get_credential_key: STORED → oauth2_55f666541ad22e39_oauth2_c2ad46dffd26cd87_existing_exchanged_credential CURRENT → oauth2_55f666541ad22e39_oauth2_c2ad46dffd26cd87_existing_exchanged_credential ✅ Keys match — fix is taking effect at the hash level. 👤 User: What's the weather in San Francisco? 🌤️ Weather Assistant event stream: [function_call] get_weather by WeatherAssistant [function_response] get_weather by WeatherAssistant [text] WeatherAssistant: 'The weather in San Francisco is Clear with a temperature of 30 degrees Celsiu...' Event counts: function_calls: 1 auth_events: 0 function_responses: 1 text_events: 1 ✅ Fix verified: tool call succeeded against the seeded credential without an adk_request_credential prompt. ``` ### 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 **Scope:** The same strip block exists at three call sites and has the same gap at all three. This PR patches all three. Patching only the tool-level pair (`tool_auth_handler.py`) and leaving the framework-level path (`auth_tool.py:AuthConfig.get_credential_key`) would leave the bug reachable for any consumer that does not work around #5327 with `get_auth_config = lambda: None`. Patching only `AuthConfig.get_credential_key` and leaving the tool-level pair would leave the bug reachable on the standard tool-level credential lookup path. **Upgrade note:** The credential_key shape changes with this fix: `redirect_uri` is no longer included in the hash. OAuth credentials cached in existing session state under the pre-fix key shape become unreachable under the new key. Users should expect a one-time re-auth prompt on the first run after upgrading. Subsequent runs use the new key normally. **Related:** - #5327 (preemptive toolset auth) - #5328 (refresh request scope) - #5329 (refreshed credential persistence, fixed in 218ea76) - #5637 (tool-level auth termination) Co-authored-by: George Weale <gweale@google.com> COPYBARA_INTEGRATE_REVIEW=#5692 from doughayden:fix/credential-key-strip-redirect-uri 3be2a85 PiperOrigin-RevId: 941217122
Co-authored-by: Xuan Yang <xygoogle@google.com> PiperOrigin-RevId: 941262556
Co-authored-by: George Weale <gweale@google.com> PiperOrigin-RevId: 941267314
Gemini thinking models require a thought_signature on generated parts, and the backend rejects replayed parts that lack one. Callers who synthesize conversation history must set b'skip_thought_signature_validator' on the fabricated part to bypass validation, and several ADK consumers hardcode that byte-string independently. Expose it once so they can depend on a single constant. Co-authored-by: George Weale <gweale@google.com> PiperOrigin-RevId: 941277709
Merge #4659 ## Summary - update `ApplicationIntegrationToolset.get_tools()` to propagate `AuthConfig.exchanged_auth_credential` to generated `IntegrationConnectorTool` instances - ensure connector tools use exchanged OAuth credentials (including runtime access token) instead of only the raw auth credential - add regression coverage for exchanged credential propagation Fixes #4553 ## Testing plan - `uv run --extra test pytest -q tests/unittests/tools/application_integration_tool/test_application_integration_toolset.py tests/unittests/tools/application_integration_tool/test_integration_connector_tool.py` ## Notes - This is a minimal fix scoped to connector-tool credential wiring only. Co-authored-by: Shangjie Chen <deanchen@google.com> COPYBARA_INTEGRATE_REVIEW=#4659 from pandego:fix/4553-ait-exchanged-auth-credential 1f9c947 PiperOrigin-RevId: 941281800
The agent ran on a schedule with a write-scoped GitHub token while feeding attacker-controlled issue title and body straight into its prompt, so a crafted issue could steer its labeling and owner-assignment actions. Removing the agent and its workflow removes that exposure. Co-authored-by: George Weale <gweale@google.com> PiperOrigin-RevId: 941289396
…cord_invocation Co-authored-by: Max Ind <maxind@google.com> PiperOrigin-RevId: 941303834
Merge #6105 ## Summary - await async/awaitable MCP header providers in async execution paths. - add unit tests verifying the async header provider functionality. Fixes #6090 Co-authored-by: Kathy Wu <wukathy@google.com> COPYBARA_INTEGRATE_REVIEW=#6105 from he-yufeng:fix/await-async-header-provider 086d352 PiperOrigin-RevId: 941317964
…l_id Co-authored-by: Shangjie Chen <deanchen@google.com> PiperOrigin-RevId: 941318373
Merge #5640 ### Link to Issue or Description of Change **1. Link to an existing issue (if applicable):** Closes: #5632 ### Problem `FirestoreSessionService.list_sessions()` always sets `Session.last_update_time` to `0.0`, even when Firestore documents contain `updateTime`. ### Solution Use the same timestamp conversion logic as `get_session()` in `list_sessions()`: - if `updateTime` is a `datetime`, use `.timestamp()` - otherwise, attempt `float(updateTime)` - fallback to `0.0` when conversion fails This keeps list responses consistent with `get_session()` and preserves accurate update timestamps. ### Testing Plan **Unit Tests:** - [x] I have added or updated unit tests for my change. - [x] All unit tests pass locally. Updated tests: - `test_list_sessions_with_user_id` - `test_list_sessions_without_user_id` Local pytest summary: - `tests/unittests/integrations/firestore/test_firestore_session_service.py` - `17 passed` **Manual End-to-End (E2E) Tests:** Reproduced with a mocked Firestore client where session docs include `updateTime`; before fix `last_update_time` was `0.0`, after fix it matches the Firestore value. ### 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. Co-authored-by: George Weale <gweale@google.com> COPYBARA_INTEGRATE_REVIEW=#5640 from kkj333:fix/firestore-list-sessions-update-time-5632 9586cc6 PiperOrigin-RevId: 941318502
When a client certificate is configured, OAuth2 token exchange and refresh now present the certificate and target the *.mtls.googleapis.com endpoint so Context-Aware Access / token binding is honored. Gated to *.googleapis.com token endpoints with a client cert available; third-party providers and non-cert environments are unchanged. Co-authored-by: George Weale <gweale@google.com> PiperOrigin-RevId: 941319195
Scope the delta check to the files the CL changed via the kokoro presubmit_request, and decouple the workspace copy so mypy module resolution is stable. Co-authored-by: George Weale <gweale@google.com> PiperOrigin-RevId: 941321034
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )