From 345a8db970d93bff6ec586e7b720ee9c3e8b633c Mon Sep 17 00:00:00 2001 From: Anas Khan <83116240+anxkhn@users.noreply.github.com> Date: Fri, 3 Jul 2026 10:40:48 +0530 Subject: [PATCH] fix(runners): widen Runner.__init__ agent param to accept BaseNode The `Runner.agent` class field is typed `Optional[BaseAgent | 'BaseNode']` and the runtime explicitly branches on `isinstance(self.agent, BaseNode)` in both `run_async` and `run_live`, so a `BaseNode` root (e.g. a `Workflow`) works at runtime. However, the `__init__` `agent` parameter was still typed `Optional[BaseAgent]`, so type checkers reject `Runner(agent=my_workflow)`. Widen the `__init__` `agent` annotation to `Optional[BaseAgent | 'BaseNode']` to match the class field, mirroring the existing forward-reference style used for the field and the `run_live` `node` parameter. This is a type-only change with no runtime behavior change. Fixes #6270 --- src/google/adk/runners.py | 2 +- tests/unittests/test_runners.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/google/adk/runners.py b/src/google/adk/runners.py index adfd7e84e8f..80c709068e9 100644 --- a/src/google/adk/runners.py +++ b/src/google/adk/runners.py @@ -203,7 +203,7 @@ def __init__( *, app: Optional[App] = None, app_name: Optional[str] = None, - agent: Optional[BaseAgent] = None, + agent: Optional[BaseAgent | 'BaseNode'] = None, node: Any = None, plugins: Optional[List[BasePlugin]] = None, artifact_service: Optional[BaseArtifactService] = None, diff --git a/tests/unittests/test_runners.py b/tests/unittests/test_runners.py index a75ce7149a0..b007945e748 100644 --- a/tests/unittests/test_runners.py +++ b/tests/unittests/test_runners.py @@ -1558,6 +1558,22 @@ def test_resolve_app_with_agent_wraps_in_app(self): assert runner.app_name == "test_app" assert runner.agent is self.root_agent + def test_resolve_app_with_base_node_via_agent_param(self): + """Test that a BaseNode root passed via `agent` is accepted.""" + from google.adk.workflow._base_node import BaseNode + + node = BaseNode(name="test_node") + runner = Runner( + app_name="test_app", + agent=node, + session_service=self.session_service, + artifact_service=self.artifact_service, + ) + assert runner.app is not None + assert runner.app.root_agent is node + assert runner.app_name == "test_app" + assert runner.agent is node + def test_resolve_app_with_node_wraps_in_app(self): """Test that a bare node is wrapped into an App.""" from google.adk.workflow._base_node import BaseNode