mirror of
https://github.com/encounter/adk-python.git
synced 2026-07-09 18:19:28 -07:00
feat: Allow custom part converters in A2A classes
This change introduces type descriptions for the functions which convert between A2A and GenAI `Part`s. It then allows passing instances of those functions to the various A2A-related functions/classes, effectively allowing users to inject their own logic for how part conversion should occur. The benefit of this pattern is that users can create decorators around the core `Part` conversion logic, which allows them to intercept the cases they care about while delegating the ones they do not to the core converter. This is a pattern we use a lot in the A2A Python SDK. One example where this type of logic is useful is for extensions: this allows extension logic to, for example, interpret an A2A DataPart into a FunctionResponse using extension-specific logic. PiperOrigin-RevId: 803186799
This commit is contained in:
committed by
Copybara-Service
parent
4df79dd5c9
commit
b05fef9ba7
@@ -441,7 +441,14 @@ class TestRemoteA2aAgentMessageHandling:
|
||||
def setup_method(self):
|
||||
"""Setup test fixtures."""
|
||||
self.agent_card = create_test_agent_card()
|
||||
self.agent = RemoteA2aAgent(name="test_agent", agent_card=self.agent_card)
|
||||
self.mock_genai_part_converter = Mock()
|
||||
self.mock_a2a_part_converter = Mock()
|
||||
self.agent = RemoteA2aAgent(
|
||||
name="test_agent",
|
||||
agent_card=self.agent_card,
|
||||
genai_part_converter=self.mock_genai_part_converter,
|
||||
a2a_part_converter=self.mock_a2a_part_converter,
|
||||
)
|
||||
|
||||
# Mock session and context
|
||||
self.mock_session = Mock(spec=Session)
|
||||
@@ -519,20 +526,17 @@ class TestRemoteA2aAgentMessageHandling:
|
||||
) as mock_convert:
|
||||
mock_convert.return_value = mock_event
|
||||
|
||||
with patch(
|
||||
"google.adk.agents.remote_a2a_agent.convert_genai_part_to_a2a_part"
|
||||
) as mock_convert_part:
|
||||
mock_a2a_part = Mock()
|
||||
mock_convert_part.return_value = mock_a2a_part
|
||||
mock_a2a_part = Mock()
|
||||
self.mock_genai_part_converter.return_value = mock_a2a_part
|
||||
|
||||
result = self.agent._construct_message_parts_from_session(
|
||||
self.mock_context
|
||||
)
|
||||
result = self.agent._construct_message_parts_from_session(
|
||||
self.mock_context
|
||||
)
|
||||
|
||||
assert len(result) == 2 # Returns tuple of (parts, context_id)
|
||||
assert len(result[0]) == 1 # parts list
|
||||
assert result[0][0] == mock_a2a_part
|
||||
assert result[1] is None # context_id
|
||||
assert len(result) == 2 # Returns tuple of (parts, context_id)
|
||||
assert len(result[0]) == 1 # parts list
|
||||
assert result[0][0] == mock_a2a_part
|
||||
assert result[1] is None # context_id
|
||||
|
||||
def test_construct_message_parts_from_session_empty_events(self):
|
||||
"""Test message parts construction with empty events."""
|
||||
@@ -575,7 +579,10 @@ class TestRemoteA2aAgentMessageHandling:
|
||||
|
||||
assert result == mock_event
|
||||
mock_convert.assert_called_once_with(
|
||||
mock_a2a_message, self.agent.name, self.mock_context
|
||||
mock_a2a_message,
|
||||
self.agent.name,
|
||||
self.mock_context,
|
||||
self.mock_a2a_part_converter,
|
||||
)
|
||||
# Check that metadata was added
|
||||
assert result.custom_metadata is not None
|
||||
@@ -613,7 +620,10 @@ class TestRemoteA2aAgentMessageHandling:
|
||||
|
||||
assert result == mock_event
|
||||
mock_convert.assert_called_once_with(
|
||||
mock_a2a_task, self.agent.name, self.mock_context
|
||||
mock_a2a_task,
|
||||
self.agent.name,
|
||||
self.mock_context,
|
||||
self.mock_a2a_part_converter,
|
||||
)
|
||||
# Check that metadata was added
|
||||
assert result.custom_metadata is not None
|
||||
@@ -649,7 +659,14 @@ class TestRemoteA2aAgentExecution:
|
||||
def setup_method(self):
|
||||
"""Setup test fixtures."""
|
||||
self.agent_card = create_test_agent_card()
|
||||
self.agent = RemoteA2aAgent(name="test_agent", agent_card=self.agent_card)
|
||||
self.mock_genai_part_converter = Mock()
|
||||
self.mock_a2a_part_converter = Mock()
|
||||
self.agent = RemoteA2aAgent(
|
||||
name="test_agent",
|
||||
agent_card=self.agent_card,
|
||||
genai_part_converter=self.mock_genai_part_converter,
|
||||
a2a_part_converter=self.mock_a2a_part_converter,
|
||||
)
|
||||
|
||||
# Mock session and context
|
||||
self.mock_session = Mock(spec=Session)
|
||||
|
||||
Reference in New Issue
Block a user