Skip to content

fix: respect A2A Message.role in inbound event conversion#5224

Open
giulio-leone wants to merge 1 commit intogoogle:mainfrom
giulio-leone:fix/a2a-inbound-role-mapping
Open

fix: respect A2A Message.role in inbound event conversion#5224
giulio-leone wants to merge 1 commit intogoogle:mainfrom
giulio-leone:fix/a2a-inbound-role-mapping

Conversation

@giulio-leone
Copy link
Copy Markdown

Summary

Fixes #5186.

convert_a2a_message_to_event() hard-coded role='model' on the GenAI Content it produced, ignoring the A2A Message.role field. This caused Role.user messages to be restored as model events.

Additionally, the task-history fallback in convert_a2a_task_to_event() (in event_converter.py) blindly took history[-1] without checking Message.role, so a trailing user message could be misattributed as agent output.

Root Cause

  • event_converter.py: Content(role="model", ...) was hard-coded in two places inside convert_a2a_message_to_event().
  • to_adk_event.py: _create_event() hard-coded role="model" with no way to override.
  • event_converter.py: convert_a2a_task_to_event() fallback path used a2a_task.history[-1] unconditionally.

Changes

File Change
converters/utils.py New a2a_role_to_genai_role() helper (Role.agent"model", Role.user"user")
converters/event_converter.py Use helper in convert_a2a_message_to_event(); filter history fallback to agent-role messages only
converters/to_adk_event.py Add role param to _create_event(); pass mapped role from convert_a2a_message_to_event()
test_event_converter.py Regression tests for role mapping + history fallback
test_to_adk.py Regression tests for role mapping
test_utils.py Unit tests for a2a_role_to_genai_role()

Testing

All 86 converter tests pass (test_event_converter.py, test_to_adk.py, test_utils.py).

@google-cla
Copy link
Copy Markdown

google-cla bot commented Apr 9, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@adk-bot
Copy link
Copy Markdown
Collaborator

adk-bot commented Apr 9, 2026

Response from ADK Triaging Agent

Hello @giulio-leone, thank you for creating this PR!

Before we can review your contribution, could you please sign our Contributor License Agreement (CLA)? You can find more information at https://cla.developers.google.com/.

Additionally, since this PR is a bug fix, could you please provide logs or a screenshot demonstrating that the fix is working as expected? This will help the reviewers to better understand and verify your changes.

Thank you!

@adk-bot adk-bot added the core [Component] This issue is related to the core interface and implementation label Apr 9, 2026
@giulio-leone
Copy link
Copy Markdown
Author

Added focused regression coverage for the fix:

  • test_event_converter.py: verifies Role.user is restored as user and that task-history fallback ignores trailing user messages
  • test_to_adk.py: verifies inbound event conversion preserves the mapped role
  • test_utils.py: verifies a2a_role_to_genai_role() mappings

Local result: 86 converter tests passed (test_event_converter.py, test_to_adk.py, test_utils.py).

This reproduces the original bug path and confirms that user-role messages are no longer misattributed as model output.

@giulio-leone giulio-leone force-pushed the fix/a2a-inbound-role-mapping branch from eb26b58 to 877d702 Compare April 9, 2026 02:34
convert_a2a_message_to_event() hard-coded role='model' on the GenAI
Content it produced, ignoring the A2A Message.role field. This caused
Role.user messages to be misattributed as model output.

Additionally, the task-history fallback in convert_a2a_task_to_event()
blindly took history[-1] without checking Message.role, so a trailing
user message could be restored as agent output.

Changes:
- Add a2a_role_to_genai_role() helper in utils.py (Role.agent→'model',
  Role.user→'user').
- event_converter.py: use the helper instead of hard-coded 'model' in
  convert_a2a_message_to_event(); filter history fallback to agent-role
  messages only.
- to_adk_event.py: add role parameter to _create_event(); pass mapped
  role from convert_a2a_message_to_event().
- Regression tests for role restoration and history fallback.
@giulio-leone giulio-leone force-pushed the fix/a2a-inbound-role-mapping branch from 877d702 to f22ca7d Compare April 9, 2026 03:01
@rohityan rohityan self-assigned this Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core [Component] This issue is related to the core interface and implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A2A inbound message conversion ignores Message.role, always maps to "model"

3 participants