1515package adka2a
1616
1717import (
18+ "bytes"
1819 "context"
1920 "encoding/base64"
2021 "encoding/json"
@@ -60,6 +61,18 @@ func IsPartialFlagSet(meta map[string]any) bool {
6061 return isSet
6162}
6263
64+ func validateDataPartJSON (d * genai.Part ) ([]byte , bool ) {
65+ if d .InlineData == nil || d .InlineData .MIMEType != "text/plain" {
66+ return nil , false
67+ }
68+ if noPrefix , ok := bytes .CutPrefix (d .InlineData .Data , []byte ("<json>" )); ok {
69+ if result , ok := bytes .CutSuffix (noPrefix , []byte ("</json>" )); ok {
70+ return result , true
71+ }
72+ }
73+ return nil , false
74+ }
75+
6376// ToA2APart converts the provided genai part to A2A equivalent. Long running tool IDs are used for attaching metadata to
6477// the relevant data parts.
6578func ToA2APart (part * genai.Part , longRunningToolIDs []string ) (a2a.Part , error ) {
@@ -81,6 +94,12 @@ func ToA2AParts(parts []*genai.Part, longRunningToolIDs []string) ([]a2a.Part, e
8194 r .Metadata = map [string ]any {ToA2AMetaKey ("thought" ): true }
8295 }
8396 result [i ] = r
97+ } else if jsonBytes , ok := validateDataPartJSON (part ); ok {
98+ var data map [string ]any
99+ if err := json .Unmarshal (jsonBytes , & data ); err != nil {
100+ return nil , err
101+ }
102+ result [i ] = a2a.DataPart {Data : data }
84103 } else if part .InlineData != nil || part .FileData != nil {
85104 r , err := toA2AFilePart (part )
86105 if err != nil {
@@ -308,13 +327,7 @@ func toGenAIFilePart(part a2a.FilePart) (*genai.Part, error) {
308327}
309328
310329func toGenAIDataPart (part a2a.DataPart ) (* genai.Part , error ) {
311- if part .Metadata == nil {
312- return toGenAITextPart (part )
313- }
314- adkMetaType , ok := part .Metadata [a2aDataPartMetaTypeKey ]
315- if ! ok {
316- return toGenAITextPart (part )
317- }
330+ adkMetaType := part .Metadata [a2aDataPartMetaTypeKey ]
318331
319332 bytes , err := json .Marshal (part .Data )
320333 if err != nil {
@@ -351,14 +364,13 @@ func toGenAIDataPart(part a2a.DataPart) (*genai.Part, error) {
351364 return & genai.Part {FunctionResponse : & val }, nil
352365
353366 default :
354- return & genai. Part { Text : string ( bytes )}, nil
355- }
356- }
357-
358- func toGenAITextPart ( part a2a. DataPart ) ( * genai. Part , error ) {
359- bytes , err := json . Marshal ( part . Data )
360- if err != nil {
361- return nil , err
367+ var jsonData [] byte
368+ prefix , suffix := [] byte ( "<json>" ), [] byte ( "</json>" )
369+ jsonData = make ([] byte , 0 , len ( prefix ) + len ( bytes ) + len ( suffix ))
370+ jsonData = append ( jsonData , prefix ... )
371+ jsonData = append ( jsonData , bytes ... )
372+ jsonData = append ( jsonData , suffix ... )
373+
374+ return & genai. Part { InlineData : & genai. Blob { Data : jsonData , MIMEType : "text/plain" }}, nil
362375 }
363- return & genai.Part {Text : string (bytes )}, nil
364376}
0 commit comments