Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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/converters/to_adk_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

from a2a.types import Message
from a2a.types import Part as A2APart
from a2a.types import Role as A2ARole
from a2a.types import Task
from a2a.types import TaskArtifactUpdateEvent
from a2a.types import TaskState
Expand Down Expand Up @@ -177,6 +178,7 @@ def _create_event(
actions: Optional[EventActions] = None,
long_running_function_ids: Optional[set[str]] = None,
partial: bool = False,
content_role: str = "model",
) -> Optional[Event]:
"""Creates an ADK event from parts and metadata."""
event_actions = actions or EventActions()
Expand All @@ -199,7 +201,7 @@ def _create_event(
),
content=(
genai_types.Content(
role="model",
role=content_role,
parts=output_parts,
)
if output_parts
Expand All @@ -211,6 +213,13 @@ def _create_event(
return event


def _a2a_role_to_content_role(role: Optional[A2ARole]) -> str:
"""Maps an A2A Role to the corresponding GenAI content role."""
if role == A2ARole.user:
return "user"
return "model"


def _parse_adk_metadata_value(value: Any) -> Any:
"""Parses ADK metadata values serialized through A2A."""
if not isinstance(value, str):
Expand Down Expand Up @@ -375,11 +384,13 @@ def convert_a2a_message_to_event(
output_parts, _ = _convert_a2a_parts_to_adk_parts(
a2a_message.parts, part_converter
)
content_role = _a2a_role_to_content_role(getattr(a2a_message, "role", None))
return _create_event(
output_parts,
invocation_context,
author,
_extract_event_actions(a2a_message.metadata),
content_role=content_role,
)

except Exception as e:
Expand Down
39 changes: 39 additions & 0 deletions tests/unittests/a2a/converters/test_to_adk.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from a2a.types import Artifact
from a2a.types import Message
from a2a.types import Part as A2APart
from a2a.types import Role as A2ARole
from a2a.types import Task
from a2a.types import TaskArtifactUpdateEvent
from a2a.types import TaskState
Expand Down Expand Up @@ -418,3 +419,41 @@ def test_convert_a2a_artifact_update_to_event_none(self):
"""Test convert_a2a_artifact_update_to_event with None."""
with pytest.raises(ValueError, match="A2A artifact update cannot be None"):
convert_a2a_artifact_update_to_event(None)

def test_convert_a2a_message_to_event_user_role(self) -> None:
"""Test that A2A user role maps to GenAI content role 'user'."""
a2a_part = Mock(spec=A2APart)
a2a_part.root = Mock(spec=TextPart)
a2a_part.root.metadata = {}
message = Message(message_id="msg-1", role=A2ARole.user, parts=[a2a_part])

mock_genai_part = genai_types.Part.from_text(text="hello from user")
mock_part_converter = Mock(return_value=[mock_genai_part])

event = convert_a2a_message_to_event(
message,
author="user",
invocation_context=self.mock_context,
part_converter=mock_part_converter,
)

assert event.content.role == "user"

def test_convert_a2a_message_to_event_agent_role(self) -> None:
"""Test that A2A agent role maps to GenAI content role 'model'."""
a2a_part = Mock(spec=A2APart)
a2a_part.root = Mock(spec=TextPart)
a2a_part.root.metadata = {}
message = Message(message_id="msg-1", role=A2ARole.agent, parts=[a2a_part])

mock_genai_part = genai_types.Part.from_text(text="hello from agent")
mock_part_converter = Mock(return_value=[mock_genai_part])

event = convert_a2a_message_to_event(
message,
author="test-agent",
invocation_context=self.mock_context,
part_converter=mock_part_converter,
)

assert event.content.role == "model"
Loading