Skip to content

Conversation

@Shubham-Kumar-2000
Copy link

@Shubham-Kumar-2000 Shubham-Kumar-2000 commented Nov 23, 2025

Motivation and Context

This integration enables agent framework agents to communicate and execute as a A2A hosted agent server.

Description

  • Implement A2A event adapter for converting agent messages to A2A protocol
  • Implement A2A executor for running agents in A2A environment
  • Add comprehensive unit tests for event adapter, and executor
  • Update agent framework core A2A module exports and type stubs
  • Integrate thread management utilities for async execution
  • Add getting started sample for A2A agent framework integration
  • Update dependencies in uv.lock

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

- Implement A2A event adapter for converting agent messages to A2A protocol
- Add A2A execution context for managing agent execution state
- Implement A2A executor for running agents in A2A environment
- Add comprehensive unit tests for event adapter, execution context, and executor
- Update agent framework core A2A module exports and type stubs
- Integrate thread management utilities for async execution
- Add getting started sample for A2A agent framework integration
- Update dependencies in uv.lock

This integration enables agent framework agents to communicate and execute within the A2A (Agent to Agent) infrastructure.
@markwallace-microsoft markwallace-microsoft added documentation Improvements or additions to documentation python labels Nov 23, 2025
@github-actions github-actions bot changed the title feat: Add Agent Framework to A2A bridge support Python: feat: Add Agent Framework to A2A bridge support Nov 23, 2025
- Reordered imports in various files for consistency and clarity.
- Updated `__all__` definitions to maintain a consistent order across modules.
- Simplified method signatures by removing unnecessary line breaks.
- Enhanced readability by adjusting formatting in several sections.
- Removed redundant comments and example scenarios in the execution context.
- Improved handling of agent messages in the event adapter.
- Added type hints for better clarity and type checking.
- Cleaned up test cases for better organization and readability.
- Deleted the test file for A2aExecutionContext as it is no longer needed.
- Updated A2aExecutor tests to remove dependencies on A2aExecutionContext and adjusted method calls accordingly.
- Modified event adapter tests to use ChatMessage instead of AgentRunResponseUpdate.
- Removed A2aExecutionContext from imports in agent_framework.a2a module and updated type hints accordingly.
Copy link
Member

@eavanvalkenburg eavanvalkenburg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea behind this, but there are some major issues with the implementation, especially the addition of the AgentThreadStore, please discuss that further with us.

from agent_framework import ChatMessage, DataContent, Role, TextContent, UriContent


class A2aEventAdapter(ABC):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use python default styles for things like abbreviations, so:

Suggested change
class A2aEventAdapter(ABC):
class A2AEventAdapter(ABC):

pass


class BaseA2aEventAdapter(A2aEventAdapter):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
class BaseA2aEventAdapter(A2aEventAdapter):
class BaseA2AEventAdapter(A2aEventAdapter):

if isinstance(content, TextContent):
parts.append(Part(root=TextPart(text=content.text)))
if isinstance(content, DataContent):
parts.append(Part(root=FilePart(file=FileWithBytes(bytes=_extract_base64_from_uri(content.uri)))))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is a method on DataContent for this:

Suggested change
parts.append(Part(root=FilePart(file=FileWithBytes(bytes=_extract_base64_from_uri(content.uri)))))
parts.append(Part(root=FilePart(file=FileWithBytes(bytes=content.get_data_bytes())))

(there is also a get_data_bytes_as_str in case the data type needs to be the string representation

# Handle URI content
parts.append(
Part(
root=FilePart(file=FileWithUri(uri=content.uri, mime_type=getattr(content, "media_type", None)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for getattr, UriContent always has media_type as a attribute.

Suggested change
root=FilePart(file=FileWithUri(uri=content.uri, mime_type=getattr(content, "media_type", None)))
root=FilePart(file=FileWithUri(uri=content.uri, mime_type=content.media_type))

)


def _extract_base64_from_uri(uri: str) -> str:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this

from ._a2a_event_adapter import A2aEventAdapter, BaseA2aEventAdapter


class A2aExecutor(AgentExecutor):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as before:

Suggested change
class A2aExecutor(AgentExecutor):
class A2AExecutor(AgentExecutor):

Example:
Demonstrating the internal processing:
```python
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sure code comments are marked appropriately, with .. code-block:: python. This applies in a number of places.

from agent_framework import ChatMessage, DataContent, Role, TextContent, UriContent


class A2aEventAdapter(ABC):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we even need this base class? Since the base class also has this single method, it doesn't add anything.

self.message_store = ChatMessageStore(messages=state.chat_message_store_state.messages, **kwargs)


class AgentThreadStorage(ABC):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are you adding this, we already have multiple ways of dealing with threads. Including serializing and deserializing them. So please don't add completely new concepts in the core package without first creating an issue and discussing the needs.

self._agent: ChatAgent | WorkflowAgent = agent
self._event_adapter: A2aEventAdapter = event_adapter if event_adapter else BaseA2aEventAdapter()

async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add the @overload decorator so that it's clear which method come from the AgentExecutor.

- Updated test cases to use A2AExecutor instead of A2aExecutor for consistency.
- Removed mock_event_adapter fixture and related tests as A2aEventAdapter is deprecated.
- Consolidated event handling tests into TestA2AExecutorEventAdapter.
- Adjusted imports in various files to reflect the removal of deprecated components.
- Ensured all references to A2aExecutor are updated to A2AExecutor across the codebase.
@Shubham-Kumar-2000
Copy link
Author

Hi @eavanvalkenburg thanks for the review.

I have further simplified the code for this feature and have addressed most of you review comments.

Regarding your major concern around AgentThreadStore I have started a discussion to finalize the approach.
#2463

Do let me know if any other changes are required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants