Skip to content

Commit 115124c

Browse files
google-genai-botcopybara-github
authored andcommitted
feat: add support for A2aAgentExecutor factory in to_a2a() function
PiperOrigin-RevId: 916015512
1 parent 27e71f3 commit 115124c

2 files changed

Lines changed: 22 additions & 17 deletions

File tree

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

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from ...runners import Runner
3636
from ...sessions.in_memory_session_service import InMemorySessionService
3737
from ..executor.a2a_agent_executor import A2aAgentExecutor
38+
from ..executor.config import A2aAgentExecutorConfig
3839
from ..experimental import a2a_experimental
3940
from .agent_card_builder import AgentCardBuilder
4041

@@ -86,6 +87,7 @@ def to_a2a(
8687
task_store: TaskStore | None = None,
8788
runner: Runner | None = None,
8889
lifespan: Callable[[Starlette], AsyncIterator[None]] | None = None,
90+
agent_executor_factory: Callable[[Runner], A2aAgentExecutor] | None = None,
8991
) -> Starlette:
9092
"""Convert an ADK agent to a A2A Starlette application.
9193
@@ -95,20 +97,21 @@ def to_a2a(
9597
port: The port for the A2A RPC URL (default: 8000)
9698
protocol: The protocol for the A2A RPC URL (default: "http")
9799
agent_card: Optional pre-built AgentCard object or path to agent card
98-
JSON. If not provided, will be built automatically from the
99-
agent.
100+
JSON. If not provided, will be built automatically from the agent.
100101
push_config_store: Optional A2A push notification config store. If not
101-
provided, an in-memory store will be created so push-notification
102-
config RPC methods are supported.
102+
provided, an in-memory store will be created so push-notification config
103+
RPC methods are supported.
103104
task_store: Optional A2A task store for persisting task state. If not
104105
provided, an in-memory store will be created.
105106
runner: Optional pre-built Runner object. If not provided, a default
106-
runner will be created using in-memory services.
107-
lifespan: Optional async context manager for Starlette lifespan
108-
events. Use this to run startup/shutdown logic (e.g. initializing
109-
database connections or loading resources). The context manager
110-
receives the Starlette app instance and can set state on
111-
``app.state``.
107+
runner will be created using in-memory services.
108+
lifespan: Optional async context manager for Starlette lifespan events.
109+
Use this to run startup/shutdown logic (e.g. initializing database
110+
connections or loading resources). The context manager receives the
111+
Starlette app instance and can set state on ``app.state``.
112+
agent_executor_factory: Optional factory function that creates an instance
113+
of A2aAgentExecutor. If not provided, a default A2aAgentExecutor will be
114+
created.
112115
113116
Returns:
114117
A Starlette application that can be run with uvicorn
@@ -148,7 +151,7 @@ async def lifespan(app):
148151
adk_logger = logging.getLogger("google_adk")
149152
adk_logger.setLevel(logging.INFO)
150153

151-
async def create_runner() -> Runner:
154+
def create_runner() -> Runner:
152155
"""Create a runner for the agent."""
153156
return Runner(
154157
app_name=agent.name or "adk_agent",
@@ -164,8 +167,10 @@ async def create_runner() -> Runner:
164167
if task_store is None:
165168
task_store = InMemoryTaskStore()
166169

167-
agent_executor = A2aAgentExecutor(
168-
runner=runner or create_runner,
170+
agent_executor = (
171+
agent_executor_factory(runner or create_runner())
172+
if agent_executor_factory is not None
173+
else A2aAgentExecutor(runner=runner or create_runner)
169174
)
170175

171176
if push_config_store is None:

tests/unittests/a2a/utils/test_agent_to_a2a.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ def test_to_a2a_creates_runner_with_correct_services(
357357
@patch("google.adk.a2a.utils.agent_to_a2a.AgentCardBuilder")
358358
@patch("google.adk.a2a.utils.agent_to_a2a.Starlette")
359359
@patch("google.adk.a2a.utils.agent_to_a2a.Runner")
360-
async def test_create_runner_function_creates_runner_correctly(
360+
def test_create_runner_function_creates_runner_correctly(
361361
self,
362362
mock_runner_class,
363363
mock_starlette_class,
@@ -391,7 +391,7 @@ async def test_create_runner_function_creates_runner_correctly(
391391
runner_func = call_args[1]["runner"]
392392

393393
# Call the runner function to verify it creates Runner correctly
394-
runner_result = await runner_func()
394+
runner_result = runner_func()
395395

396396
# Verify Runner was created with correct parameters
397397
mock_runner_class.assert_called_once_with(
@@ -420,7 +420,7 @@ async def test_create_runner_function_creates_runner_correctly(
420420
@patch("google.adk.a2a.utils.agent_to_a2a.AgentCardBuilder")
421421
@patch("google.adk.a2a.utils.agent_to_a2a.Starlette")
422422
@patch("google.adk.a2a.utils.agent_to_a2a.Runner")
423-
async def test_create_runner_function_with_agent_without_name(
423+
def test_create_runner_function_with_agent_without_name(
424424
self,
425425
mock_runner_class,
426426
mock_starlette_class,
@@ -455,7 +455,7 @@ async def test_create_runner_function_with_agent_without_name(
455455
runner_func = call_args[1]["runner"]
456456

457457
# Call the runner function to verify it creates Runner correctly
458-
await runner_func()
458+
runner_func()
459459

460460
# Verify Runner was created with default app_name when agent has no name
461461
mock_runner_class.assert_called_once_with(

0 commit comments

Comments
 (0)