Skip to content

Commit dcc485b

Browse files
google-genai-botcopybara-github
authored andcommitted
feat: emit a TaskStatusUpdateEvent for ADK events with no output parts but with event.actions
PiperOrigin-RevId: 896929519
1 parent b0715d7 commit dcc485b

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

src/google/adk/a2a/converters/from_adk_event.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,23 @@ def convert_event_to_a2a_events(
218218
),
219219
)
220220
)
221+
elif _serialize_value(event.actions) is not None:
222+
a2a_events.append(
223+
TaskStatusUpdateEvent(
224+
task_id=task_id,
225+
context_id=context_id,
226+
status=TaskStatus(
227+
state=TaskState.working,
228+
message=Message(
229+
message_id=str(uuid.uuid4()),
230+
role=Role.agent,
231+
parts=[],
232+
),
233+
timestamp=datetime.now(timezone.utc).isoformat(),
234+
),
235+
final=False,
236+
)
237+
)
221238

222239
a2a_events = _add_event_metadata(event, a2a_events)
223240
return a2a_events
@@ -280,7 +297,10 @@ def _add_event_metadata(
280297
metadata[_get_adk_metadata_key(field_name)] = value
281298

282299
for a2a_event in a2a_events:
283-
if isinstance(a2a_event, TaskStatusUpdateEvent):
300+
if (
301+
isinstance(a2a_event, TaskStatusUpdateEvent)
302+
and a2a_event.status.message
303+
):
284304
a2a_event.status.message.metadata = metadata.copy()
285305
elif isinstance(a2a_event, TaskArtifactUpdateEvent):
286306
a2a_event.artifact.metadata = metadata.copy()

tests/unittests/a2a/integration/test_client_server.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from a2a.types import TextPart
2222
from google.adk.agents.remote_a2a_agent import A2A_METADATA_PREFIX
2323
from google.adk.events.event import Event
24+
from google.adk.events.event_actions import EventActions
2425
from google.adk.platform import uuid as platform_uuid
2526
from google.adk.runners import Runner
2627
from google.adk.sessions.in_memory_session_service import InMemorySessionService
@@ -47,6 +48,11 @@ async def mock_run_async(**kwargs):
4748
content=types.Content(parts=[types.Part(text=" world")]),
4849
partial=True,
4950
)
51+
yield Event(
52+
author="FakeAgent",
53+
partial=True,
54+
actions=EventActions(artifact_delta={"file1": 1}),
55+
)
5056
yield Event(
5157
author="FakeAgent",
5258
content=types.Content(parts=[types.Part(text="Hello world")]),
@@ -92,18 +98,23 @@ async def test_streaming_adk_to_streaming_a2a():
9298
new_message = types.Content(parts=[types.Part(text="Hi")], role="user")
9399

94100
texts = []
101+
actions = []
95102
async for event in client_runner.run_async(
96103
user_id="test_user", session_id="test_session", new_message=new_message
97104
):
98105
if event.content and event.content.parts:
99106
for p in event.content.parts:
100107
if p.text:
101108
texts.append(p.text)
109+
if event.actions and event.actions.artifact_delta:
110+
actions.append(event.actions)
102111

103112
assert len(received_requests) == 1
104113
assert received_requests[0]["session_id"] is not None
105114

106115
assert texts == ["Hello", " world", "Hello world"]
116+
assert len(actions) == 1
117+
assert actions[0].artifact_delta == {"file1": 1}
107118

108119

109120
@pytest.mark.asyncio

0 commit comments

Comments
 (0)