Merge https://github.com/google/adk-python/pull/2641
This PR adds a custom `User-Agent` header to all requests made via `RestApiTool`. This allows backend services to identify traffic originating from the ADK. The header format is `google-adk/<version> (tool: <tool_name>)`, where `<version>` is the current version of the `google-adk` package, fetched dynamically from `google.adk.version`, and `<tool_name>` is the name of the specific `RestApiTool` instance.
**Associated Issue**
Fixes#2676
**Testing Plan**
**Unit Tests**
I ran the full suite of unit tests locally to ensure the changes did not introduce any regressions. All tests passed successfully.
```bash
$ pytest ./tests/unittests
================================= 4202 passed, 2459 warnings in 44.68s ====================
```
The warnings are related to existing experimental features and are not affected by this change.
**Manual End-to-End (E2E) Test**
I performed a manual test to ensure the integrated flow works as expected.
* **Setup:** Created a clean virtual environment (`~/venvs/adk-e2e-test`) and installed the locally built `google-adk` package using `uv venv --seed` and `pip install dist/google_adk-*.whl`. Ran a custom `mock_server.py` script (using Flask) in one terminal to listen for requests and print headers. Ran a custom `run_test_tool.py` script in a second terminal to send a request using the modified `RestApiTool`.
* **Execution:** The `run_test_tool.py` script successfully sent a POST request to the mock server's `/test` endpoint. The mock server received the request and printed the headers.
**`run_test_tool.py` Output:**
```json
{
"message": "Request received successfully!"
}
```
**`mock_server.py` Output (Headers):**
```text
--- Request Received ---
Headers:
Host: 127.0.0.1:8000
User-Agent: google-adk/1.12.0 (tool: TestTool)
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Type: application/json
Content-Length: 2
------------------------
```
The `User-Agent: google-adk/1.12.0 (tool: TestTool)` header confirms the change is working as intended, dynamically fetching the package version and including the tool name.
**Checklist**
* [x] Associated issue linked
* [x] Unit tests passed
* [x] End-to-end test performed and results documented
* [x] Code formatted with `./autoformat.sh`
---
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2641 from rcsantana777:feat/add-user-agent a9a9375306c18bb7ba501276cbf76693e70a87ad
PiperOrigin-RevId: 798232385
So far we had a default docstring for the `execute-sql` tool and for non-default write modes we were concatenating more content to it. This was working fine in Python 3.9-3.12 but broke in Python 3.13 because of a nuanced difference in the string concatenation to the `__doc__` property of a function b/433914562#comment4. This change makes the docstring management more robust and readable.
PiperOrigin-RevId: 797843736
This can help to provide more context and information about the table, like parent-child relationship, and row deletion policy etc.
PiperOrigin-RevId: 797562858
Introduce `DynamicPickleType` to handle session actions, using sqlalchemy-spanner `SpannerPickleType` when the database dialect is Spanner.
Connects to a Spanner database to store session data persistently in tables.
# Example using Spanner database:
`session_service = DatabaseSessionService(db_url="spanner+spanner:///projects/project-id/instances/instance-id/databases/database-id")`
# Example adk web command:
`adk web --session_service_uri="spanner+spanner:///projects/project-id/instances/instance-id/databases/database-id"`
PiperOrigin-RevId: 797416610
Merge https://github.com/google/adk-python/pull/2212
This PR closes issue #2202
ADK was not parsing the required attribute when using LiteLLM, letting the LLM decide what is required vs not, not respecting function definitions.
## Test Plan
There's a fork of adk-python that is being running live for over 2 weeks in our production environment with millions of requests per day.
Below you can find a screenshot of the unit tests passing. I've also added one change to the test cases to cover this scenario
<img width="1904" height="483" alt="image" src="https://github.com/user-attachments/assets/5a6eb069-63ae-45a3-baca-6b01543f56fb" />
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2212 from thiagosalvatore:main 7de4037d8016389313f3fb22df40c12bac578523
PiperOrigin-RevId: 797393698