diff --git a/google.go b/google.go index b371978..1f7eff7 100644 --- a/google.go +++ b/google.go @@ -2,8 +2,11 @@ package go_llm import ( "context" + "encoding/base64" "encoding/json" "fmt" + "io" + "net/http" "github.com/google/generative-ai-go/genai" "google.golang.org/api/option" @@ -54,6 +57,57 @@ func (g google) requestToChatHistory(in Request, model *genai.GenerativeModel) ( content.Role = "user" } + for _, img := range c.Images { + if img.Url != "" { + // gemini does not support URLs, so we need to download the image and convert it to a blob + + // Download the image from the URL + resp, err := http.Get(img.Url) + if err != nil { + panic(fmt.Sprintf("error downloading image: %v", err)) + } + defer resp.Body.Close() + + // Check the Content-Length to ensure it's not over 20MB + if resp.ContentLength > 20*1024*1024 { + panic(fmt.Sprintf("image size exceeds 20MB: %d bytes", resp.ContentLength)) + } + + // Read the content into a byte slice + data, err := io.ReadAll(resp.Body) + if err != nil { + panic(fmt.Sprintf("error reading image data: %v", err)) + } + + // Ensure the MIME type is appropriate + mimeType := http.DetectContentType(data) + switch mimeType { + case "image/jpeg", "image/png", "image/gif": + // MIME type is valid + default: + panic(fmt.Sprintf("unsupported image MIME type: %s", mimeType)) + } + + // Create a genai.Blob using the validated image data + content.Parts = append(content.Parts, genai.Blob{ + MIMEType: mimeType, + Data: data, + }) + + } else { + // convert base64 to blob + b, e := base64.StdEncoding.DecodeString(img.Base64) + if e != nil { + panic(fmt.Sprintf("error decoding base64: %v", e)) + } + + content.Parts = append(content.Parts, genai.Blob{ + MIMEType: img.ContentType, + Data: b, + }) + } + } + // if this is the last message, we want to add to history, we want it to be the parts if i == len(in.Messages)-1 { return &res, cs, content.Parts