Skip to content

Commit f7de2ae

Browse files
Update proto conversion utilities
1 parent d2e869f commit f7de2ae

File tree

1 file changed

+75
-14
lines changed

1 file changed

+75
-14
lines changed

src/a2a/utils/proto_utils.py

Lines changed: 75 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)