mirror of
https://github.com/encounter/adk-python.git
synced 2026-07-09 18:19:28 -07:00
chore: Enhance a2a part converters
a. fix binary data conversion b. support thoughts, code execution result, executable codes conversion PiperOrigin-RevId: 775827259
This commit is contained in:
committed by
Copybara-Service
parent
738d1a8b84
commit
832a633351
@@ -18,6 +18,7 @@ module containing utilities for conversion betwen A2A Part and Google GenAI Part
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import json
|
||||
import logging
|
||||
import sys
|
||||
@@ -43,8 +44,11 @@ from ...utils.feature_decorator import working_in_progress
|
||||
logger = logging.getLogger('google_adk.' + __name__)
|
||||
|
||||
A2A_DATA_PART_METADATA_TYPE_KEY = 'type'
|
||||
A2A_DATA_PART_METADATA_IS_LONG_RUNNING_KEY = 'is_long_running'
|
||||
A2A_DATA_PART_METADATA_TYPE_FUNCTION_CALL = 'function_call'
|
||||
A2A_DATA_PART_METADATA_TYPE_FUNCTION_RESPONSE = 'function_response'
|
||||
A2A_DATA_PART_METADATA_TYPE_CODE_EXECUTION_RESULT = 'code_execution_result'
|
||||
A2A_DATA_PART_METADATA_TYPE_EXECUTABLE_CODE = 'executable_code'
|
||||
|
||||
|
||||
@working_in_progress
|
||||
@@ -67,7 +71,8 @@ def convert_a2a_part_to_genai_part(
|
||||
elif isinstance(part.file, a2a_types.FileWithBytes):
|
||||
return genai_types.Part(
|
||||
inline_data=genai_types.Blob(
|
||||
data=part.file.bytes.encode('utf-8'), mime_type=part.file.mimeType
|
||||
data=base64.b64decode(part.file.bytes),
|
||||
mime_type=part.file.mimeType,
|
||||
)
|
||||
)
|
||||
else:
|
||||
@@ -84,7 +89,11 @@ def convert_a2a_part_to_genai_part(
|
||||
# response.
|
||||
# TODO once A2A defined how to suervice such information, migrate below
|
||||
# logic accordinlgy
|
||||
if part.metadata and A2A_DATA_PART_METADATA_TYPE_KEY in part.metadata:
|
||||
if (
|
||||
part.metadata
|
||||
and _get_adk_metadata_key(A2A_DATA_PART_METADATA_TYPE_KEY)
|
||||
in part.metadata
|
||||
):
|
||||
if (
|
||||
part.metadata[_get_adk_metadata_key(A2A_DATA_PART_METADATA_TYPE_KEY)]
|
||||
== A2A_DATA_PART_METADATA_TYPE_FUNCTION_CALL
|
||||
@@ -103,6 +112,24 @@ def convert_a2a_part_to_genai_part(
|
||||
part.data, by_alias=True
|
||||
)
|
||||
)
|
||||
if (
|
||||
part.metadata[_get_adk_metadata_key(A2A_DATA_PART_METADATA_TYPE_KEY)]
|
||||
== A2A_DATA_PART_METADATA_TYPE_CODE_EXECUTION_RESULT
|
||||
):
|
||||
return genai_types.Part(
|
||||
code_execution_result=genai_types.CodeExecutionResult.model_validate(
|
||||
part.data, by_alias=True
|
||||
)
|
||||
)
|
||||
if (
|
||||
part.metadata[_get_adk_metadata_key(A2A_DATA_PART_METADATA_TYPE_KEY)]
|
||||
== A2A_DATA_PART_METADATA_TYPE_EXECUTABLE_CODE
|
||||
):
|
||||
return genai_types.Part(
|
||||
executable_code=genai_types.ExecutableCode.model_validate(
|
||||
part.data, by_alias=True
|
||||
)
|
||||
)
|
||||
return genai_types.Part(text=json.dumps(part.data))
|
||||
|
||||
logger.warning(
|
||||
@@ -118,27 +145,40 @@ def convert_genai_part_to_a2a_part(
|
||||
part: genai_types.Part,
|
||||
) -> Optional[a2a_types.Part]:
|
||||
"""Convert a Google GenAI Part to an A2A Part."""
|
||||
|
||||
if part.text:
|
||||
return a2a_types.TextPart(text=part.text)
|
||||
a2a_part = a2a_types.TextPart(text=part.text)
|
||||
if part.thought is not None:
|
||||
a2a_part.metadata = {_get_adk_metadata_key('thought'): part.thought}
|
||||
return a2a_types.Part(root=a2a_part)
|
||||
|
||||
if part.file_data:
|
||||
return a2a_types.FilePart(
|
||||
file=a2a_types.FileWithUri(
|
||||
uri=part.file_data.file_uri,
|
||||
mimeType=part.file_data.mime_type,
|
||||
return a2a_types.Part(
|
||||
root=a2a_types.FilePart(
|
||||
file=a2a_types.FileWithUri(
|
||||
uri=part.file_data.file_uri,
|
||||
mimeType=part.file_data.mime_type,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
if part.inline_data:
|
||||
return a2a_types.Part(
|
||||
root=a2a_types.FilePart(
|
||||
file=a2a_types.FileWithBytes(
|
||||
bytes=part.inline_data.data,
|
||||
mimeType=part.inline_data.mime_type,
|
||||
)
|
||||
a2a_part = a2a_types.FilePart(
|
||||
file=a2a_types.FileWithBytes(
|
||||
bytes=base64.b64encode(part.inline_data.data).decode('utf-8'),
|
||||
mimeType=part.inline_data.mime_type,
|
||||
)
|
||||
)
|
||||
|
||||
if part.video_metadata:
|
||||
a2a_part.metadata = {
|
||||
_get_adk_metadata_key(
|
||||
'video_metadata'
|
||||
): part.video_metadata.model_dump(by_alias=True, exclude_none=True)
|
||||
}
|
||||
|
||||
return a2a_types.Part(root=a2a_part)
|
||||
|
||||
# Conver the funcall and function reponse to A2A DataPart.
|
||||
# This is mainly for converting human in the loop and auth request and
|
||||
# response.
|
||||
@@ -151,9 +191,9 @@ def convert_genai_part_to_a2a_part(
|
||||
by_alias=True, exclude_none=True
|
||||
),
|
||||
metadata={
|
||||
A2A_DATA_PART_METADATA_TYPE_KEY: (
|
||||
A2A_DATA_PART_METADATA_TYPE_FUNCTION_CALL
|
||||
)
|
||||
_get_adk_metadata_key(
|
||||
A2A_DATA_PART_METADATA_TYPE_KEY
|
||||
): A2A_DATA_PART_METADATA_TYPE_FUNCTION_CALL
|
||||
},
|
||||
)
|
||||
)
|
||||
@@ -165,9 +205,37 @@ def convert_genai_part_to_a2a_part(
|
||||
by_alias=True, exclude_none=True
|
||||
),
|
||||
metadata={
|
||||
A2A_DATA_PART_METADATA_TYPE_KEY: (
|
||||
A2A_DATA_PART_METADATA_TYPE_FUNCTION_RESPONSE
|
||||
)
|
||||
_get_adk_metadata_key(
|
||||
A2A_DATA_PART_METADATA_TYPE_KEY
|
||||
): A2A_DATA_PART_METADATA_TYPE_FUNCTION_RESPONSE
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
if part.code_execution_result:
|
||||
return a2a_types.Part(
|
||||
root=a2a_types.DataPart(
|
||||
data=part.code_execution_result.model_dump(
|
||||
by_alias=True, exclude_none=True
|
||||
),
|
||||
metadata={
|
||||
_get_adk_metadata_key(
|
||||
A2A_DATA_PART_METADATA_TYPE_KEY
|
||||
): A2A_DATA_PART_METADATA_TYPE_CODE_EXECUTION_RESULT
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
if part.executable_code:
|
||||
return a2a_types.Part(
|
||||
root=a2a_types.DataPart(
|
||||
data=part.executable_code.model_dump(
|
||||
by_alias=True, exclude_none=True
|
||||
),
|
||||
metadata={
|
||||
_get_adk_metadata_key(
|
||||
A2A_DATA_PART_METADATA_TYPE_KEY
|
||||
): A2A_DATA_PART_METADATA_TYPE_EXECUTABLE_CODE
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user