@@ -408,6 +408,31 @@ def _create_mock_function_call_for_required_user_input(
408408 return output_parts , long_running_function_ids
409409
410410
411+ def _extract_all_metadata_fields (metadata : Any ) -> dict [str , Any ]:
412+ """Extracts all GenAI metadata fields from A2A metadata."""
413+ metadata_dict = _compat .meta_to_dict (metadata )
414+ if not metadata_dict :
415+ return {}
416+ fields = {
417+ "grounding_metadata" : _extract_genai_metadata (
418+ metadata_dict , "grounding_metadata" , genai_types .GroundingMetadata
419+ ),
420+ "custom_metadata" : _extract_genai_metadata (
421+ metadata_dict , "custom_metadata" , None
422+ ),
423+ "usage_metadata" : _extract_genai_metadata (
424+ metadata_dict ,
425+ "usage_metadata" ,
426+ genai_types .GenerateContentResponseUsageMetadata ,
427+ ),
428+ "error_code" : _extract_genai_metadata (metadata_dict , "error_code" , None ),
429+ "citation_metadata" : _extract_genai_metadata (
430+ metadata_dict , "citation_metadata" , genai_types .CitationMetadata
431+ ),
432+ }
433+ return {k : v for k , v in fields .items () if v is not None }
434+
435+
411436@a2a_experimental
412437def convert_a2a_task_to_event (
413438 a2a_task : Task ,
@@ -438,6 +463,8 @@ def convert_a2a_task_to_event(
438463 event_actions = EventActions ()
439464 output_parts = []
440465 long_running_function_ids = set ()
466+ metadata_fields : dict [str , Any ] = {}
467+ status_message = _compat .normalize_message (a2a_task .status .message )
441468 if a2a_task .artifacts :
442469 artifact_parts = [
443470 part for artifact in a2a_task .artifacts for part in artifact .parts
@@ -446,10 +473,11 @@ def convert_a2a_task_to_event(
446473 event_actions = _merge_event_actions (
447474 event_actions , _extract_event_actions (artifact .metadata )
448475 )
476+ if not metadata_fields :
477+ metadata_fields = _extract_all_metadata_fields (artifact .metadata )
449478 output_parts , _ = _convert_a2a_parts_to_adk_parts (
450479 artifact_parts , part_converter
451480 )
452- status_message = _compat .normalize_message (a2a_task .status .message )
453481 if status_message and (
454482 a2a_task .status .state == _compat .TS_INPUT_REQUIRED
455483 or a2a_task .status .state == _compat .TS_AUTH_REQUIRED
@@ -458,11 +486,15 @@ def convert_a2a_task_to_event(
458486 event_actions ,
459487 _extract_event_actions (status_message .metadata ),
460488 )
489+ if not metadata_fields :
490+ metadata_fields = _extract_all_metadata_fields (status_message .metadata )
461491 parts , ids = _convert_a2a_parts_to_adk_parts (
462492 status_message .parts , part_converter
463493 )
464494 output_parts .extend (parts )
465495 long_running_function_ids .update (ids )
496+ elif status_message and not metadata_fields :
497+ metadata_fields = _extract_all_metadata_fields (status_message .metadata )
466498
467499 output_parts , long_running_function_ids = (
468500 _create_mock_function_call_for_required_user_input (
@@ -476,6 +508,7 @@ def convert_a2a_task_to_event(
476508 author ,
477509 event_actions ,
478510 long_running_function_ids ,
511+ ** metadata_fields ,
479512 )
480513
481514 except Exception as e :
@@ -515,12 +548,14 @@ def convert_a2a_message_to_event(
515548 a2a_message .parts , part_converter
516549 )
517550 content_role = _a2a_role_to_content_role (getattr (a2a_message , "role" , None ))
551+ metadata_fields = _extract_all_metadata_fields (a2a_message .metadata )
518552 return _create_event (
519553 output_parts ,
520554 invocation_context ,
521555 author ,
522556 _extract_event_actions (a2a_message .metadata ),
523557 content_role = content_role ,
558+ ** metadata_fields ,
524559 )
525560
526561 except Exception as e :
@@ -553,9 +588,11 @@ def convert_a2a_status_update_to_event(
553588 output_parts = []
554589 long_running_function_ids = set ()
555590 event_actions = EventActions ()
591+ metadata_fields = {}
556592 status_message = _compat .normalize_message (a2a_status_update .status .message )
557593 if status_message :
558594 event_actions = _extract_event_actions (status_message .metadata )
595+ metadata_fields = _extract_all_metadata_fields (status_message .metadata )
559596 parts , ids = _convert_a2a_parts_to_adk_parts (
560597 status_message .parts , part_converter
561598 )
@@ -576,6 +613,7 @@ def convert_a2a_status_update_to_event(
576613 author ,
577614 event_actions ,
578615 long_running_function_ids ,
616+ ** metadata_fields ,
579617 )
580618 except Exception as e :
581619 logger .error ("Failed to convert A2A status update to event: %s" , e )
@@ -608,28 +646,16 @@ def convert_a2a_artifact_update_to_event(
608646 output_parts , _ = _convert_a2a_parts_to_adk_parts (
609647 a2a_artifact_update .artifact .parts , part_converter
610648 )
611- metadata_dict = _compat .meta_to_dict (a2a_artifact_update .artifact .metadata )
649+ metadata_fields = _extract_all_metadata_fields (
650+ a2a_artifact_update .artifact .metadata
651+ )
612652 return _create_event (
613653 output_parts ,
614654 invocation_context ,
615655 author ,
616656 _extract_event_actions (a2a_artifact_update .artifact .metadata ),
617657 partial = not a2a_artifact_update .last_chunk ,
618- grounding_metadata = _extract_genai_metadata (
619- metadata_dict , "grounding_metadata" , genai_types .GroundingMetadata
620- ),
621- custom_metadata = _extract_genai_metadata (
622- metadata_dict , "custom_metadata" , None
623- ),
624- usage_metadata = _extract_genai_metadata (
625- metadata_dict ,
626- "usage_metadata" ,
627- genai_types .GenerateContentResponseUsageMetadata ,
628- ),
629- error_code = _extract_genai_metadata (metadata_dict , "error_code" , None ),
630- citation_metadata = _extract_genai_metadata (
631- metadata_dict , "citation_metadata" , genai_types .CitationMetadata
632- ),
658+ ** metadata_fields ,
633659 )
634660 except Exception as e :
635661 logger .error ("Failed to convert A2A artifact update to event: %s" , e )
0 commit comments