Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
76f5f81
feat: Add support for custom task store in to_a2a function
secprog Nov 20, 2025
ff62647
Apply suggestion from @gemini-code-assist[bot]
secprog Nov 20, 2025
8c065db
Remove unused import 'Any' from agent_to_a2a.py
secprog Nov 20, 2025
933ad25
Refactor task_store type to use TaskStore
secprog Nov 20, 2025
2953b28
Correct type hint for task_store in agent_to_a2a
secprog Nov 20, 2025
019001b
Update tests/unittests/a2a/utils/test_agent_to_a2a.py
secprog Nov 20, 2025
b02954d
Update test_agent_to_a2a to use TaskStore for custom task store mock
secprog Nov 20, 2025
2a6703c
Merge branch 'main' of https://github.com/secprog/adk-python
secprog Nov 20, 2025
870f1a7
Update tests/unittests/a2a/utils/test_agent_to_a2a.py
secprog Nov 20, 2025
f84d2e5
Update src/google/adk/a2a/utils/agent_to_a2a.py
secprog Nov 20, 2025
6f26528
Update tests/unittests/a2a/utils/test_agent_to_a2a.py
secprog Nov 20, 2025
bfdac2d
Update src/google/adk/a2a/utils/agent_to_a2a.py
secprog Nov 20, 2025
9454d4e
Remove unused mock imports in test_agent_to_a2a.py to streamline the …
secprog Nov 20, 2025
8ba63c6
Merge branch 'main' into main
secprog Nov 20, 2025
3017486
Merge branch 'main' into main
secprog Nov 20, 2025
f7eaef5
Merge branch 'main' into main
secprog Nov 21, 2025
429a928
refactor: Clean up import statements in experiment and run_experiment…
secprog Nov 21, 2025
e5fb5fb
Merge branch 'main' into main
secprog Nov 21, 2025
8efe8a7
Merge branch 'main' into main
secprog Nov 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion src/google/adk/a2a/utils/agent_to_a2a.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
else:
raise e

from typing import Any
from typing import Optional
from typing import Union

Expand Down Expand Up @@ -91,6 +92,7 @@ def to_a2a(
protocol: str = "http",
agent_card: Optional[Union[AgentCard, str]] = None,
runner: Optional[Runner] = None,
task_store: Optional[Any] = None,
) -> Starlette:
"""Convert an ADK agent to a A2A Starlette application.

Expand All @@ -104,6 +106,9 @@ def to_a2a(
agent.
runner: Optional pre-built Runner object. If not provided, a default
runner will be created using in-memory services.
task_store: Optional task store instance. If not provided, an
InMemoryTaskStore will be created. Must be compatible with
DefaultRequestHandler's task_store parameter.

Returns:
A Starlette application that can be run with uvicorn
Expand All @@ -115,6 +120,11 @@ def to_a2a(

# Or with custom agent card:
app = to_a2a(agent, agent_card=my_custom_agent_card)

# Or with custom task store:
from a2a.server.tasks import MyCustomTaskStore
custom_store = MyCustomTaskStore()
app = to_a2a(agent, task_store=custom_store)
"""
# Set up ADK logging to ensure logs are visible when using uvicorn directly
setup_adk_logger(logging.INFO)
Expand All @@ -132,7 +142,8 @@ async def create_runner() -> Runner:
)

# Create A2A components
task_store = InMemoryTaskStore()
if task_store is None:
task_store = InMemoryTaskStore()

agent_executor = A2aAgentExecutor(
runner=runner or create_runner,
Expand Down
45 changes: 45 additions & 0 deletions tests/unittests/a2a/utils/test_agent_to_a2a.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,51 @@ def test_to_a2a_with_custom_runner(
"startup", mock_app.add_event_handler.call_args[0][1]
)

@patch("google.adk.a2a.utils.agent_to_a2a.A2aAgentExecutor")
@patch("google.adk.a2a.utils.agent_to_a2a.DefaultRequestHandler")
@patch("google.adk.a2a.utils.agent_to_a2a.InMemoryTaskStore")
@patch("google.adk.a2a.utils.agent_to_a2a.AgentCardBuilder")
@patch("google.adk.a2a.utils.agent_to_a2a.Starlette")
def test_to_a2a_with_custom_task_store(
self,
mock_starlette_class,
mock_card_builder_class,
mock_task_store_class,
mock_request_handler_class,
mock_agent_executor_class,
):
"""Test to_a2a with a custom task store."""
# Arrange
mock_app = Mock(spec=Starlette)
mock_starlette_class.return_value = mock_app
custom_task_store = Mock(spec=InMemoryTaskStore)
mock_agent_executor = Mock(spec=A2aAgentExecutor)
mock_agent_executor_class.return_value = mock_agent_executor
mock_request_handler = Mock(spec=DefaultRequestHandler)
mock_request_handler_class.return_value = mock_request_handler
mock_card_builder = Mock(spec=AgentCardBuilder)
mock_card_builder_class.return_value = mock_card_builder

# Act
result = to_a2a(self.mock_agent, task_store=custom_task_store)

# Assert
assert result == mock_app
mock_starlette_class.assert_called_once()
# Verify InMemoryTaskStore was NOT created since we provided a custom one
mock_task_store_class.assert_not_called()
mock_agent_executor_class.assert_called_once()
# Verify the custom task store was used
mock_request_handler_class.assert_called_once_with(
agent_executor=mock_agent_executor, task_store=custom_task_store
)
mock_card_builder_class.assert_called_once_with(
agent=self.mock_agent, rpc_url="http://localhost:8000/"
)
mock_app.add_event_handler.assert_called_once_with(
"startup", mock_app.add_event_handler.call_args[0][1]
)

@patch("google.adk.a2a.utils.agent_to_a2a.A2aAgentExecutor")
@patch("google.adk.a2a.utils.agent_to_a2a.DefaultRequestHandler")
@patch("google.adk.a2a.utils.agent_to_a2a.InMemoryTaskStore")
Expand Down