feat(workflow): Allow ToolNode to accept JSON string or Content inputs#6065
feat(workflow): Allow ToolNode to accept JSON string or Content inputs#6065baptmont wants to merge 6 commits into
Conversation
Enable ToolNode to receive JSON-formatted strings or types.Content objects in workflows. This supports flexible upstream formats, such as output from LLM agents or raw user content, automatically parsing them into dictionary arguments for downstream tools.
|
Response from ADK Triaging Agent Hello @baptmont, thank you for contributing this PR! This looks like a great enhancement to I noticed that the automated You can run it manually across all files using: pre-commit run --all-filesMore details about the development setup and code formatting can be found in our Contribution Guidelines. This will help us get your pull request reviewed and merged more quickly. Thank you! |
|
/adk-pr-analyze |
|
Hi @baptmont, Thank you for your contribution! We appreciate you taking the time to submit this pull request. Your PR has been received by the team and is currently under review. We will provide feedback as soon as we have an update to share. |
|
Hi @swapydapy , can you please review this. |
Merge #6065 **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: N/A - Related: N/A **2. Or, if no issue exists, describe the change:** **Problem:** Previously, `ToolNode` in ADK workflows required input to be strictly a Python `dict` or `None`. This limited workflow flexibility, preventing users from chaining a `ToolNode` directly downstream of nodes (like LLM Agents or custom function nodes) that output inputs as serialized JSON strings or `types.Content` objects without manual parsing boilerplate. **Solution:** Enhanced `ToolNode._run_impl` in [_tool_node.py](file:///usr/local/google/home/westerberg/Documents/github/adk-python-fork/src/google/adk/workflow/_tool_node.py) to dynamically coerce input formats before tool execution: - Extract text from `types.Content` when received. - Strip and deserialize JSON strings via `json.loads` if received. - Coerce `None` to `{}`. - Keep strict validation raising `TypeError` for non-dictionary representations (e.g. lists, invalid JSON). --- ### Testing Plan **Unit Tests:** - [x] I have added or updated unit tests for my change. - [x] All unit tests pass locally. **Pytest Summary:** ``` tests/unittests/workflow/test_tool_node.py ....... [100%] ======================== 7 passed, 4 warnings in 2.80s ========================= ``` **Manual End-to-End (E2E) Tests:** Verified all workflow tests pass locally with no regressions: ``` uv run pytest tests/unittests/workflow/ ... ==== 600 passed, 10 skipped, 26 xfailed, 9 xpassed, 237 warnings in 15.17s ===== ``` --- ### 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. Co-authored-by: George Weale <gweale@google.com> COPYBARA_INTEGRATE_REVIEW=#6065 from baptmont:tool_node_args 36edc1f PiperOrigin-RevId: 940575182
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
1. Link to an existing issue (if applicable):
2. Or, if no issue exists, describe the change:
Problem:
Previously,
ToolNodein ADK workflows required input to be strictly a PythondictorNone. This limited workflow flexibility, preventing users from chaining aToolNodedirectly downstream of nodes (like LLM Agents or custom function nodes) that output inputs as serialized JSON strings ortypes.Contentobjects without manual parsing boilerplate.Solution:
Enhanced
ToolNode._run_implin _tool_node.py to dynamically coerce input formats before tool execution:types.Contentwhen received.json.loadsif received.Noneto{}.TypeErrorfor non-dictionary representations (e.g. lists, invalid JSON).Testing Plan
Unit Tests:
Pytest Summary:
Manual End-to-End (E2E) Tests:
Verified all workflow tests pass locally with no regressions:
Checklist