From c31f7ef925e7188fe43df0100de0cb2e2163673d 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 9802801dcad..886629e01d8 100644 --- a/src/google/adk/runners.py +++ b/src/google/adk/runners.py @@ -177,7 +177,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 925769951d8..5ad81ab3b2c 100644 --- a/tests/unittests/test_runners.py +++ b/tests/unittests/test_runners.py @@ -1409,6 +1409,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