From 8964a83634ecce1508fa4c4191f0b3ccb40eaa13 Mon Sep 17 00:00:00 2001 From: Hugo Aguirre Parra Date: Wed, 24 Dec 2025 19:12:28 +0000 Subject: [PATCH 1/2] fix(go/plugins/googlegenai): include thoughtSignature in part metadata --- go/plugins/googlegenai/gemini.go | 51 +++++++++++++++++++------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/go/plugins/googlegenai/gemini.go b/go/plugins/googlegenai/gemini.go index c7e49a8bec..3c3e42483f 100644 --- a/go/plugins/googlegenai/gemini.go +++ b/go/plugins/googlegenai/gemini.go @@ -807,6 +807,7 @@ func translateCandidate(cand *genai.Candidate) (*ai.ModelResponse, error) { if part.FileData != nil { partFound++ p = ai.NewMediaPart(part.FileData.MIMEType, part.FileData.FileURI) + } if part.FunctionCall != nil { partFound++ @@ -836,6 +837,13 @@ func translateCandidate(cand *genai.Candidate) (*ai.ModelResponse, error) { continue } + if !part.Thought && len(part.ThoughtSignature) > 0 { + if p.Metadata == nil { + p.Metadata = make(map[string]any) + } + p.Metadata["signature"] = part.ThoughtSignature + } + msg.Content = append(msg.Content, p) } m.Message = msg @@ -892,37 +900,33 @@ func toGeminiParts(parts []*ai.Part) ([]*genai.Part, error) { // toGeminiPart converts a [ai.Part] to a [genai.Part]. func toGeminiPart(p *ai.Part) (*genai.Part, error) { + var gp *genai.Part switch { case p.IsReasoning(): - // TODO: go-genai does not support genai.NewPartFromThought() - signature := []byte{} - if p.Metadata != nil { - if sig, ok := p.Metadata["signature"].([]byte); ok { - signature = sig - } + // NOTE: go-genai does not support genai.NewPartFromThought() + gp = &genai.Part{ + Thought: true, + Text: p.Text, } - return &genai.Part{ - Thought: true, - Text: p.Text, - ThoughtSignature: signature, - }, nil case p.IsText(): - return genai.NewPartFromText(p.Text), nil + gp = genai.NewPartFromText(p.Text) case p.IsMedia(): if strings.HasPrefix(p.Text, "data:") { contentType, data, err := uri.Data(p) if err != nil { return nil, err } - return genai.NewPartFromBytes(data, contentType), nil + gp = genai.NewPartFromBytes(data, contentType) + } else { + gp = genai.NewPartFromURI(p.Text, p.ContentType) } - return genai.NewPartFromURI(p.Text, p.ContentType), nil case p.IsData(): contentType, data, err := uri.Data(p) if err != nil { return nil, err } - return genai.NewPartFromBytes(data, contentType), nil + gp = genai.NewPartFromBytes(data, contentType) + case p.IsToolResponse(): toolResp := p.ToolResponse var output map[string]any @@ -934,8 +938,7 @@ func toGeminiPart(p *ai.Part) (*genai.Part, error) { "content": toolResp.Output, } } - fr := genai.NewPartFromFunctionResponse(toolResp.Name, output) - return fr, nil + gp = genai.NewPartFromFunctionResponse(toolResp.Name, output) case p.IsToolRequest(): toolReq := p.ToolRequest var input map[string]any @@ -946,11 +949,19 @@ func toGeminiPart(p *ai.Part) (*genai.Part, error) { "input": toolReq.Input, } } - fc := genai.NewPartFromFunctionCall(toolReq.Name, input) - return fc, nil + gp = genai.NewPartFromFunctionCall(toolReq.Name, input) + default: - panic("unknown part type in a request") + return nil, fmt.Errorf("unknown part in the request: %q", p.Kind) + } + + if p.Metadata != nil { + if sig, ok := p.Metadata["signature"].([]byte); ok { + gp.ThoughtSignature = sig + } } + + return gp, nil } // validToolName checks whether the provided tool name matches the From a81163a1566354eeb7aaeff70b49531b79b35878 Mon Sep 17 00:00:00 2001 From: Hugo Aguirre Date: Wed, 24 Dec 2025 13:19:58 -0600 Subject: [PATCH 2/2] include signature in Reasoning parts Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- go/plugins/googlegenai/gemini.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/go/plugins/googlegenai/gemini.go b/go/plugins/googlegenai/gemini.go index 3c3e42483f..d4d48dd9a1 100644 --- a/go/plugins/googlegenai/gemini.go +++ b/go/plugins/googlegenai/gemini.go @@ -837,12 +837,12 @@ func translateCandidate(cand *genai.Candidate) (*ai.ModelResponse, error) { continue } - if !part.Thought && len(part.ThoughtSignature) > 0 { - if p.Metadata == nil { - p.Metadata = make(map[string]any) - } - p.Metadata["signature"] = part.ThoughtSignature - } + if len(part.ThoughtSignature) > 0 { + if p.Metadata == nil { + p.Metadata = make(map[string]any) + } + p.Metadata["signature"] = part.ThoughtSignature + } msg.Content = append(msg.Content, p) }