Skip to content

Commit 156d235

Browse files
dongyuj1copybara-github
authored andcommitted
feat: Allow injecting a custom Runner into agent_to_a2a
This change adds an optional `runner` parameter to the `to_a2a` function, enabling users to provide a pre-configured `Runner` instance instead of always using the default in-memory services. A new test case has been added to verify this functionality. closes #3104 Co-authored-by: Dongyu Jia <dongyuj@google.com> PiperOrigin-RevId: 826526861
1 parent 338c3c8 commit 156d235

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

src/google/adk/a2a/utils/agent_to_a2a.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ def to_a2a(
9090
port: int = 8000,
9191
protocol: str = "http",
9292
agent_card: Optional[Union[AgentCard, str]] = None,
93+
runner: Optional[Runner] = None,
9394
) -> Starlette:
9495
"""Convert an ADK agent to a A2A Starlette application.
9596
@@ -101,6 +102,8 @@ def to_a2a(
101102
agent_card: Optional pre-built AgentCard object or path to agent card
102103
JSON. If not provided, will be built automatically from the
103104
agent.
105+
runner: Optional pre-built Runner object. If not provided, a default
106+
runner will be created using in-memory services.
104107
105108
Returns:
106109
A Starlette application that can be run with uvicorn
@@ -132,7 +135,7 @@ async def create_runner() -> Runner:
132135
task_store = InMemoryTaskStore()
133136

134137
agent_executor = A2aAgentExecutor(
135-
runner=create_runner,
138+
runner=runner or create_runner,
136139
)
137140

138141
request_handler = DefaultRequestHandler(

tests/unittests/a2a/utils/test_agent_to_a2a.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,51 @@ def test_to_a2a_default_parameters(
103103
"startup", mock_app.add_event_handler.call_args[0][1]
104104
)
105105

106+
@patch("google.adk.a2a.utils.agent_to_a2a.A2aAgentExecutor")
107+
@patch("google.adk.a2a.utils.agent_to_a2a.DefaultRequestHandler")
108+
@patch("google.adk.a2a.utils.agent_to_a2a.InMemoryTaskStore")
109+
@patch("google.adk.a2a.utils.agent_to_a2a.AgentCardBuilder")
110+
@patch("google.adk.a2a.utils.agent_to_a2a.Starlette")
111+
def test_to_a2a_with_custom_runner(
112+
self,
113+
mock_starlette_class,
114+
mock_card_builder_class,
115+
mock_task_store_class,
116+
mock_request_handler_class,
117+
mock_agent_executor_class,
118+
):
119+
"""Test to_a2a with a custom runner."""
120+
# Arrange
121+
mock_app = Mock(spec=Starlette)
122+
mock_starlette_class.return_value = mock_app
123+
mock_task_store = Mock(spec=InMemoryTaskStore)
124+
mock_task_store_class.return_value = mock_task_store
125+
mock_agent_executor = Mock(spec=A2aAgentExecutor)
126+
mock_agent_executor_class.return_value = mock_agent_executor
127+
mock_request_handler = Mock(spec=DefaultRequestHandler)
128+
mock_request_handler_class.return_value = mock_request_handler
129+
mock_card_builder = Mock(spec=AgentCardBuilder)
130+
mock_card_builder_class.return_value = mock_card_builder
131+
custom_runner = Mock(spec=Runner)
132+
133+
# Act
134+
result = to_a2a(self.mock_agent, runner=custom_runner)
135+
136+
# Assert
137+
assert result == mock_app
138+
mock_starlette_class.assert_called_once()
139+
mock_task_store_class.assert_called_once()
140+
mock_agent_executor_class.assert_called_once_with(runner=custom_runner)
141+
mock_request_handler_class.assert_called_once_with(
142+
agent_executor=mock_agent_executor, task_store=mock_task_store
143+
)
144+
mock_card_builder_class.assert_called_once_with(
145+
agent=self.mock_agent, rpc_url="http://localhost:8000/"
146+
)
147+
mock_app.add_event_handler.assert_called_once_with(
148+
"startup", mock_app.add_event_handler.call_args[0][1]
149+
)
150+
106151
@patch("google.adk.a2a.utils.agent_to_a2a.A2aAgentExecutor")
107152
@patch("google.adk.a2a.utils.agent_to_a2a.DefaultRequestHandler")
108153
@patch("google.adk.a2a.utils.agent_to_a2a.InMemoryTaskStore")

0 commit comments

Comments
 (0)