Skip to content

Commit 79d9a84

Browse files
committed
Fix A2A metadata round-trip serialization
Signed-off-by: Yizuki_Ame <yinzimike@gmail.com>
1 parent e3567a6 commit 79d9a84

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from collections.abc import Callable
1818
from datetime import datetime
1919
from datetime import timezone
20+
import json
2021
import logging
2122
from typing import Any
2223
from typing import Dict
@@ -266,6 +267,14 @@ def _serialize_value(value: Any) -> Optional[Any]:
266267
logger.warning("Failed to serialize Pydantic model, falling back: %s", e)
267268
return str(value)
268269

270+
if isinstance(value, (dict, list, str, bool, int, float)):
271+
return value
272+
273+
try:
274+
return json.loads(json.dumps(value))
275+
except (TypeError, ValueError):
276+
pass
277+
269278
return str(value)
270279

271280

tests/unittests/a2a/converters/test_event_round_trip.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
from a2a.types import TaskStatusUpdateEvent
2424
from google.adk.a2a.converters.from_adk_event import convert_event_to_a2a_events
2525
from google.adk.a2a.converters.from_adk_event import create_error_status_event
26+
from google.adk.a2a.converters.to_adk_event import _parse_adk_metadata_value
2627
from google.adk.a2a.converters.to_adk_event import convert_a2a_artifact_update_to_event
2728
from google.adk.a2a.converters.to_adk_event import convert_a2a_status_update_to_event
29+
from google.adk.a2a.converters.utils import _get_adk_metadata_key
2830
from google.adk.agents.invocation_context import InvocationContext
2931
from google.adk.events.event import Event
3032
from google.genai import types as genai_types
@@ -206,3 +208,43 @@ def test_round_trip_function_response_event():
206208
assert restored_event.content.parts[0].function_response.response == {
207209
"result": "success"
208210
}
211+
212+
213+
def test_round_trip_custom_metadata_preserves_structured_values():
214+
original_custom_metadata = {
215+
"flag": True,
216+
"count": 42,
217+
"nested": {"key": "val"},
218+
"tags": ["a", "b"],
219+
}
220+
original_event = Event(
221+
invocation_id="test_invocation",
222+
author="test_agent",
223+
branch="main",
224+
content=genai_types.Content(
225+
role="model",
226+
parts=[genai_types.Part.from_text(text="Hello world!")],
227+
),
228+
custom_metadata=original_custom_metadata,
229+
)
230+
agents_artifacts: Dict[str, str] = {}
231+
232+
a2a_events = convert_event_to_a2a_events(
233+
event=original_event,
234+
agents_artifacts=agents_artifacts,
235+
task_id="task1",
236+
context_id="context1",
237+
)
238+
239+
assert len(a2a_events) == 1
240+
a2a_event = a2a_events[0]
241+
assert isinstance(a2a_event, TaskArtifactUpdateEvent)
242+
243+
serialized_metadata = a2a_event.artifact.metadata[
244+
_get_adk_metadata_key("custom_metadata")
245+
]
246+
247+
assert not isinstance(serialized_metadata, str)
248+
assert (
249+
_parse_adk_metadata_value(serialized_metadata) == original_custom_metadata
250+
)

0 commit comments

Comments
 (0)