Describe the bug
As of v1.16.0 when using a remote A2A agent in streaming mode, the client agent receives some duplicated events (see screenshot below). In particular:
- The client agent receives an event from the server with the message that was sent with the A2A request. This is particularly annoying since the A2A request is constructed to include all previous events up to the last event from the remote agent, so the client will see in subsequent turns the same event/s twice and from different authors.
- The last event from the remote agent is returned twice, once from the actual ADK event in the remote agent and once from the
TaskArtifactUpdateEvent issued by the A2aAgentExecutor which contains as artifact the last message from the remote agent (if the agent completed its invocation regularly)
To Reproduce
- Modify the basic a2a sample from
contributing/samples/a2a_root to enable streaming
- Change the server to expose streaming support by modifying the agent card in the
to_app function used in the contributing/samples/a2a_root/remote_a2a/hello_world/agent.py as follows:
card_builder = AgentCardBuilder(
agent=agent,
rpc_url=rpc_url,
capabilities=AgentCapabilities(
streaming=True,
),
)
- change the client to request streaming responses by modifying the
contributing/samples/a2a_root/agent.py:
from a2a.client.client import ClientConfig as A2AClientConfig
from a2a.client.client_factory import ClientFactory as A2AClientFactory
from a2a.types import TransportProtocol as A2ATransport
from google.adk.agents.remote_a2a_agent import AGENT_CARD_WELL_KNOWN_PATH
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent
# Configure the client factory to support streaming
client_config = A2AClientConfig(
streaming=True,
polling=False,
supported_transports=[A2ATransport.jsonrpc],
)
a2a_client_factory = A2AClientFactory(config=client_config)
root_agent = RemoteA2aAgent(
name="hello_world_agent",
description=(
"Helpful assistant that can roll dice and check if numbers are prime."
),
agent_card=f"http://localhost:8001/{AGENT_CARD_WELL_KNOWN_PATH}",
a2a_client_factory=a2a_client_factory,
)
- Run client and server as described here
- Do a simple test
Expected behavior
The a2a request should not appear as an event authored by the remote agent, and a single event should be generated for the agent final response.
Screenshots
Here we can see that the a2a request is mirrored as a server generated event, and that we have two events for the final answer:
Possible solution:
These could be a potential way to address the behaviour reported above:
- Do not include the request message when updating the task status to submitted in
A2aAgentExecutor.execute
- Do not send the
TaskArtifactUpdateEvent after the agent is done in A2aAgentExecutor._handle_request. And possibly avoid including the message in the TaskStatusUpdateEvent in case the agent has failed or required user input.
Desktop:
- OS: Linux
- Python version(python -V): 3.11
- ADK version(pip show google-adk): 1.16.0
Model Information:
- Are you using LiteLLM: Yes
- Model used: gpt-4.1
Describe the bug
As of v1.16.0 when using a remote A2A agent in streaming mode, the client agent receives some duplicated events (see screenshot below). In particular:
TaskArtifactUpdateEventissued by theA2aAgentExecutorwhich contains as artifact the last message from the remote agent (if the agent completed its invocation regularly)To Reproduce
contributing/samples/a2a_rootto enable streamingto_appfunction used in thecontributing/samples/a2a_root/remote_a2a/hello_world/agent.pyas follows:contributing/samples/a2a_root/agent.py:Expected behavior
The a2a request should not appear as an event authored by the remote agent, and a single event should be generated for the agent final response.
Screenshots
Here we can see that the a2a request is mirrored as a server generated event, and that we have two events for the final answer:
Possible solution:
These could be a potential way to address the behaviour reported above:
A2aAgentExecutor.executeTaskArtifactUpdateEventafter the agent is done inA2aAgentExecutor._handle_request. And possibly avoid including the message in theTaskStatusUpdateEventin case the agent has failed or required user input.Desktop:
Model Information: