@@ -46,14 +46,7 @@ def metadata(
4646 ) -> struct_pb2 .Struct | None :
4747 if metadata is None :
4848 return None
49- return struct_pb2 .Struct (
50- # TODO: Add support for other types.
51- fields = {
52- key : struct_pb2 .Value (string_value = value )
53- for key , value in metadata .items ()
54- if isinstance (value , str )
55- }
56- )
49+ return dict_to_struct (metadata )
5750
5851 @classmethod
5952 def part (cls , part : types .Part ) -> a2a_pb2 .Part :
@@ -81,7 +74,9 @@ def file(
8174 ) -> a2a_pb2 .FilePart :
8275 if isinstance (file , types .FileWithUri ):
8376 return a2a_pb2 .FilePart (
84- file_with_uri = file .uri , mime_type = file .mime_type , name = file .name
77+ file_with_uri = file .uri ,
78+ mime_type = file .mime_type ,
79+ name = file .name
8580 )
8681 return a2a_pb2 .FilePart (
8782 file_with_bytes = file .bytes .encode ('utf-8' ),
@@ -324,6 +319,23 @@ def capabilities(
324319 return a2a_pb2 .AgentCapabilities (
325320 streaming = bool (capabilities .streaming ),
326321 push_notifications = bool (capabilities .push_notifications ),
322+ extensions = [
323+ cls .extension (x ) for x in capabilities .extensions
324+ ]
325+ if capabilities .extensions
326+ else None ,
327+ )
328+
329+ @classmethod
330+ def extension (
331+ cls ,
332+ extension : types .AgentExtension ,
333+ ) -> a2a_pb2 .AgentExtension :
334+ return a2a_pb2 .AgentExtension (
335+ uri = extension .uri ,
336+ description = extension .description ,
337+ params = dict_to_struct (extension .params ),
338+ required = extension .required ,
327339 )
328340
329341 @classmethod
@@ -477,11 +489,9 @@ def message(cls, message: a2a_pb2.Message) -> types.Message:
477489
478490 @classmethod
479491 def metadata (cls , metadata : struct_pb2 .Struct ) -> dict [str , Any ]:
480- return {
481- key : value .string_value
482- for key , value in metadata .fields .items ()
483- if value .string_value
484- }
492+ if not metadata :
493+ return {}
494+ return struct_to_dict (metadata )
485495
486496 @classmethod
487497 def part (cls , part : a2a_pb2 .Part ) -> types .Part :
@@ -777,6 +787,23 @@ def capabilities(
777787 return types .AgentCapabilities (
778788 streaming = capabilities .streaming ,
779789 push_notifications = capabilities .push_notifications ,
790+ extensions = [
791+ cls .agent_extension (x ) for x in capabilities .extensions
792+ ]
793+ if capabilities .extensions
794+ else None ,
795+ )
796+
797+ @classmethod
798+ def agent_extension (
799+ cls ,
800+ extension : a2a_pb2 .AgentExtension ,
801+ ) -> types .AgentExtension :
802+ return types .AgentExtension (
803+ uri = extension .uri ,
804+ description = extension .description ,
805+ params = struct_to_dict (extension .params ),
806+ required = extension .required ,
780807 )
781808
782809 @classmethod
@@ -916,3 +943,37 @@ def role(cls, role: a2a_pb2.Role) -> types.Role:
916943 return types .Role .agent
917944 case _:
918945 return types .Role .agent
946+
947+
948+ def struct_to_dict (struct : struct_pb2 .Struct ) -> dict [str , Any ]:
949+ """Converts a Struct proto to a Python dict."""
950+
951+ def convert (value : struct_pb2 .Value ) -> Any :
952+ if value .HasField ('list_value' ):
953+ return [convert (v ) for v in value .list_value .values ]
954+ elif value .HasField ('struct_value' ):
955+ return {k : convert (v ) for k , v in value .struct_value .fields .items ()}
956+ elif value .HasField ('number_value' ):
957+ return value .number_value
958+ elif value .HasField ('string_value' ):
959+ return value .string_value
960+ elif value .HasField ('bool_value' ):
961+ return value .bool_value
962+ elif value .HasField ('null_value' ):
963+ return None
964+ else :
965+ raise ValueError (f'Unsupported type: { value } ' )
966+
967+ return {k : convert (v ) for k , v in struct .fields .items ()}
968+
969+
970+ def dict_to_struct (dictionary : dict [str , Any ]) -> struct_pb2 .Struct :
971+ """Converts a Python dict to a Struct proto."""
972+ struct = struct_pb2 .Struct ()
973+ for key , val in dictionary .items ():
974+ if isinstance (val , dict ):
975+ struct [key ] = dict_to_struct (val )
976+ else :
977+ struct [key ] = val
978+ return struct
979+
0 commit comments